头图

vue3 source code

Brother Cui's mini-vue is very popular recently, it has soared to 5.9k star.

It seems that everyone is very convoluted, and I can't fall behind. This is the mini-vue I implemented after learning, including the implementation of the mini-vue code, study notes and some thinking.

In the future, I will continue to update the study notes and mind maps. Currently, I have written reactive and drawn effect mind maps.

reactive mind map

reactive.png

createReactiveObject

Create reactive objects
  • parameter

    • target target object
    • proxyMap cache map
    • baseHandlers handler object
  • step

    • Get an existing proxy object, performance optimization
    • Create proxy object, set cache
 function createReactiveObject(target, proxyMap, baseHandlers) {
  const existingProxy = proxyMap.get(taget);

  // 使用缓存优化
  if (existingProxy) {
    return existingProxy;
  }

  const proxy = new Proxy(taget, baseHandlers);
  proxyMap.set(taget, proxy);

  return proxy;
}

baseHandlers

  1. mutableHandlers
Reactive processing object, non-read-only isReadonly = false, non-shallow response shallow = false
 const get = createGetter();
const set = createSetter();

export const mutableHandlers = {
  get,
  set,
};
  1. readonlyHandlers
The processing object of readonly, read-only isReadonly = true, non-shallow response shallow = false
 const readonlyGet = createGetter(true);

export const readonlyHandlers = {
  get: readonlyGet,
  set(target, key) {
    // 不能更改
    console.warn(`${target} of ${key} can't be setted, it's a readonly object`);
    return true;
  },
};
  1. shallowReadonlyHandlers
The processing object of shallowReadonly, read-only isReadonly = true, shallow response shallow = true, set is consistent with readonlyHandlers
 const shallowReadonlyGet = createGetter(true, true);

export const shallowReadonlyHandlers = Object.assign({}, readonlyHandlers, {
  get: shallowReadonlyGet,
});

createGetter

Generate get function
 function createGetter(isReadonly = false, shallow = false) {
  return (target, key, receiver) => {
    if (key === ReactiveFlags.IS_REACTIVE) {
      // 判断是否为 readonly 对象
      return !isReadonly;
    } else if (key === ReactiveFlags.IS_READONLY) {
      // 判断是否为 reactive 对象
      return isReadonly;
    }

    // 如果不是只读对象,收集依赖
    // 只读对象不能更改,所以不需要收集
    if (!isReadonly) {
      track(target, "get", key);
    }

    // 获取属性值
    const res = Reflect.get(target, key, receiver);

    // 只对最外层最响应式,不执行嵌套对象的响应式转换
    if (shallow) {
      return res;
    }

    // 执行嵌套对象的响应式转换
    if (isObjectOrArray(res)) {
      return isReadonly ? readonly(res) : reactive(res);
    }
    return res;
  };
}

createSetter

Generate set function
 function createSetter() {
  return (target, key, value, receiver) => {
    // 设置属性值
    const res = Reflect.set(target, key, value, receiver);

    // 触发 依赖
    trigger(target, "set", key);
    return res;
  };
}

Utility function

  • isProxy determines whether it is a reactive or readonly type
  • isReactive is a reactive type
  • isReadonly is a readonly type

shellingfordly
87 声望14 粉丝

普通前端程序员