总结Vue3响应式API之reactive模块

133 阅读1分钟

几个有代表性典型的api

  • reactive
  • readonly
  • shallowReadonly
  • isReadonly
  • isReactive
  • isProxy tips:reactive和shawllowReactive的区别就对标readonly和shallowReadonly的区别就清楚了,对以下内容建议在熟悉了各个api的用途后再阅读,相信会给大家理解reactive相关api带来一定的帮助

reactive、readonly、shallowReadonly

// 这三个api底层都是调用这个方法不同的是对参数的控制
function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
    // 此处省略了部分代码,只看核心部分...
  
    const existingProxy = proxyMap.get(target);
    // 已经定义过了直接返回
    if (existingProxy) {
        return existingProxy;
    }
    
    // 获取 target 类型
    const targetType = getTargetType(target);
    
    // 传进来的不是'Object'、'Array'、'Map'、'Set'、'WeakMap'、'WeakSet'
    // 直接把值返回
    if (targetType === 0 /* INVALID */) {
        return target;
    }
    
    // 初始化一个proxy,根据不同的数据类型传递不同的handlers
    // handler 其实就是一个对象 { get:get的处理逻辑, set: set的处理逻辑 }
    // reactive 的 get 处理值为 object 的时候会 reactive(值) 而 shawllowReadonly 不会
    // shawlloReadOnly 和 readonly 的 set 逻辑是一样的,不会接受改动
    const proxy = new Proxy(target, targetType === 2 ? collectionHandlers : baseHandlers);
    
    // 存起来避免同一个 target重复创建
    proxyMap.set(target, proxy);
    return proxy;
}

isReadonly,isReactive,isProxy

这三个的源码逻辑就非常简单了,直接判断一下属性是true还是false

function isReadonly(value) {
    // readonly 创建的 proxy 会在其 get 上加一个逻辑 
    // if (key === "__v_isReadonly") return true; 下面的同理
    return !!(value && value["__v_isReadonly"]);
}
function isReactive(value) {
    // readonly 出来的值并不能通过 isReactive 的判断
    if (isReadonly(value)) {
        return isReactive(value["__v_raw"]);
    }
    return !!(value && value["__v_isReactive"]);
}
function isShallow(value) {
    return !!(value && value["__v_isShallow"]);
}
function isProxy(value) {
    // reactive 或者 readonly 的值肯定是 proxy
    return isReactive(value) || isReadonly(value);
}

后话

后面还会再推出对 computed 的总结,上面有讲错的地方请在评论区指出,谢谢! 2022.5.22 上海浦东 2:08