几个有代表性典型的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