3-reactive实现

154 阅读1分钟

reactive实现

  • 用什么实现响应式?
    • Proxy
  • 怎么去避免同一个对象的反复代理?
    • 用WeakMap收集,当再次代理就返回代理的对象
  • 怎么避免代理的对象被再次代理?
    • 用标志来判断
function isObject(obj) {
  return typeof obj === "object" && obj !== null;
}

const enum ReactiveFlags = {
  IS_REACTIVE = '__v_isReactive'
}

// 桶 key只能是对象
const reactiveMap = new WeakMap();

function reactive(target) {
  if(!isObject(target)) return;
  // 对象是被代理过的,返回代理对象
  if(target[ReactiveFlags.IS_REACTIVE]) {
    return target;
  }

  let exisitingProxy = reactiveMap.get(target);
  // 已经产生代理对象,返回代理对象(避免重复创建)
  if(exisitingProxy) {
    return exisitingProxy;
  }

  // 第一次普通对象代理,我们会通过 new Proxy代理一次
  // 下一次传递代理对象,看一下是否已被代理,如果proxy有get方法说明已经被代理过了
  const proxy = new Proxy(target, {
    // 用Reflect是把this -> 代理对象
    get(target, key, receiver) {
      // 添加标识
      if(key === ReactiveFlags.IS_REACTIVE) {
        return true;
      }
      return Reflect.get(target, key, receiver);
    },
    set(target, key, value, receiver) {
      // 返回一个设置成功
      return Reflect.set(target, key, value, receiver);
    }
  });

  // 把原对象和代理对象关联
  reactiveMap.set(target, proxy);
  return proxy;
}