實現Vue 3數據響應

前言

就在昨天Vue 3的源碼公佈了,在此以前相信對Vue有了解的開發者都知道Vue 3會改用Proxy來代替Object.defineProperty實現數據響應。至於爲何要用Proxy,你們從去年年末到如今這段時間多多少少都有了解過了吧。這兩天都在看Vue 3相關的東西,此文旨在鞏固用Proxy實現響應數據的過程,以便更好理解源碼的實現。javascript

Proxy實現數據響應

const toProxy = new WeakMap();
const toRaw = new WeakMap();
// toProxy、toRaw都是用於存放代理過的對象的哈希表,防止重複代理

function upDate() { // 至關於vue數據更新後執行的操做
  console.log('數據更新');
}

function isObject(target) {
  return typeof target === 'object' && target !== null;
}

function reactive(target) {
  if (!isObject(target)) { // 若是不是對象就直接返回
    return target;
  }
  if (toProxy.get(target)) { // 若是代理表中已經存在,就把這個結果返回
    return toProxy.get(target);
  }
  if (toRaw.has(target)) { // 若是這個對象已經被代理了,就把對象返回
    return target;
  }
  const handlers = {
    get(target, key, receiver) {
      let res = Reflect.get(target, key, receiver);
      if(isObject(target[key])){
        return reactive(res); // 遞歸
      }
      return res;
    },
    set(target, key, value, receiver) {
      if (!target.hasOwnProperty(key)) {
        upDate();
      }
      return Reflect.set(target, key, value, receiver);
    },
    deleteProperty(target, key) {
      return Reflect.defineProperty(target, key);
    }
  }
  let observed = new Proxy(target, handlers);
  toProxy.set(target, observed); // target是原對象,存放原對象代理後的結果
  toRaw.set(observed, target); // target是已經代理過的對象
  return observed;
}

let obj = {
  name: 'Vue 3'
}
let vueData = reactive(obj);
vueData.name = '1'

複製代碼

上述代碼就實現了數據響應,看完這些,再去看源碼中的reactive.ts應該就很清晰了,原理是一致的,這裏就大概是缺了數據變化的依賴收集和執行,還有部分拓展。vue

相關文章
相關標籤/搜索