1-vue-reactive简单的实现

145 阅读1分钟

响应式实现

  • proxy/WeakMap
const reactiveMap = new WeakMap();
const enum ReactiveFlag {
  IS_REACTIVE = '__v_isReactive'
}
// 将数据转化成响应式数据
// 1.实现同一个对象代理多次返回同一个代理
// 2.代理对象再次代理直接返回
export function reactive(target) {
  // 判断传的东西是不是对象
  if(!isObject(target)) return;
  
  //第一次查是没有这个属性的,会代理一次,后面的是代理过的回去访问get,有这个属性就直接使用这个target了
  if(target[ReactiveFlag.IS_REACTIVE]) {
    return target;
  }

  let existingProxy = reactiveMap.get(target);
  if(existingProxy) {
    return existingProxy;
  }
  // 第一次普通对象代理,我们会通过new Proxy代理一次
  // 下一次你传递的是proxy,看一下它有没有代理过,如果访问这个proxy 有get方法的时候说明访问过了

  // 并没有重新定义属性,只是代理,在取值的时候会调用get,当赋值值的时候调用set
  // receiver代理对象
  const proxy = new Proxy(target, {
    get(target, key, receiver) {
      if(key === ReactiveFlag.IS_REACTIVE) {
        return true;
      }
      // 会把this变成代理对象
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      return Reflect.set(target, key, value, receiver);
    }
  });
  // 把原对象和代理对象关联起来
  reactiveMap.set(target, proxy);
  return proxy;
}

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