vue3响应式原理

2020/04/20 vue

vue3源码里reactive方法简单实现

1、 源码

const toProxy = new WeakMap(); // 存放代理后的对象
const toRaw = new WeakMap(); // 存放代理前的对象

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

function trigger(){
  console.log('触发视图更新');
}

function reactive(target){
  if(!isObject(target)){
    return target;
  }
  // 如果代理表中已经存在,返回代理
  if(toProxy.get(target)){
    return toProxy.get(target);
  }
  // 如果这个对象已经被代理,返回这个对象
  if(toRaw.get(target)){
    return target;
  }

  let handlers = {
    set(target, key, value, receiver){ // 设置值的时候触发
      // 如果触发的是私有属性的话就触发更新
      if(target.hasOwnProperty(key)){
        trigger();
      }
      return Reflect.set(target, key, value, receiver);
    },
    get(target, key, receiver){ // 获取值的时候触发
      const res = Reflect.get(target, key, receiver);
      if(isObject(target[key])){
        return receiver(res);
      }
      return res;
    },
    deleteProperty(target, key){ // 删除值的时候触发
      return Reflect.deleteProperty(target, key);
    }
  }

  let observed = new Proxy(target, handlers);
  toProxy.set(target, observed);
  toRgba.set(observed, target);
  return observed;
}

let obj = {
  name: 'cat',
  array: [1,2,3]
}

let p = reactive(obj);
p.name = 'said';
console.log(obj);

Search

    Table of Contents