vue3.0源码核心--reactive
reactivity核心模块reactive前言一、createReactiveObject二、baseHandlers三、collectionHandlers1.引入库2.读入数据总结前言上文我们学习了vue.3.1响应式系统reactivity,今天我们来系统学习下核心模块reactive源码一、createReactiveObjectcreateReactiveObject的作用是将targ
reactivity核心模块reactive
前言
上文我们学习了vue.3.1响应式系统reactivity,今天我们来系统学习下核心模块reactive源码
Vue3中响应数据核心是 reactive , reactive 中的实现是由 proxy 加 effect 组合,先来看一下 reactive 方法的定义
一、reactive
export function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
export function reactive(target: object) {
// if trying to observe a readonly proxy, return the readonly version.
// 如果目标对象是一个只读的响应数据,则直接返回目标对象
if (target && (target as Target).__v_isReadonly) {
return target
}
// 否则调用 createReactiveObject 创建 observe
return createReactiveObject(
target,
false,
mutableHandlers,
mutableCollectionHandlers,
reactiveMap
)
}
二、createReactiveObject
createReactiveObject的作用是将target转化为响应式对象,话不多说上代码
代码版本3.1.4
function createReactiveObject(
target: Target,
isReadonly: boolean,
baseHandlers: ProxyHandler<any>,
collectionHandlers: ProxyHandler<any>
proxyMap: WeakMap<Target, any>
) {
// 被转化的target必须是object
if (!isObject(target)) {
if (__DEV__) {
console.warn(`value cannot be made reactive: ${String(target)}`)
}
return target
}
// target is already a Proxy, return it.
// exception: calling readonly() on a reactive object
if (
target[ReactiveFlags.RAW] &&
!(isReadonly && target[ReactiveFlags.IS_REACTIVE])
) {
return target
}
// target already has corresponding Proxy 目标已经有相应的代理
const existingProxy = proxyMap.get(target)
if (existingProxy) {
return existingProxy
}
// only a whitelist of value types can be observed.白名单
//只有target在可转化类型白名单里才会进行转化,否则直接返回target
const targetType = getTargetType(target)
if (targetType === TargetType.INVALID) {
return target
}
// 转化proxy对象,并将转化后的对象挂载到target的__v_readonly(只读模式)或__v_reactive(非只读模式)属性上
const proxy = new Proxy(
target,
// Set、WeakSet、Map、WeakMap类型用的collectionHandlers,其他对象类型使用baseHandlers
targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers
)
proxyMap.set(target, proxy)
return proxy
}
那么在这里3.1是优化了3.0的createReactiveObject方法内可转化类型白名单方法的实现,会校验target的__v_skip是否为true、target类型是否在白名单里、target是否为冻结对象,同时满足才会继续转化
三、目标对象
代码如下(版本3.1.4):
// 同时满足3个条即为可以观察的目标对象
// 1. 没有打上__v_skip标记
// 2. 是可以观察的值类型
// 3. 没有被frozen
function getTargetType(value: Target) {
return value[ReactiveFlags.SKIP] || !Object.isExtensible(value)
? TargetType.INVALID
: targetTypeMap(toRawType(value))
}
// 可以被观察的值类型
function targetTypeMap(rawType: string) {
switch (rawType) {
case 'Object':
case 'Array':
return TargetType.COMMON
case 'Map':
case 'Set':
case 'WeakMap':
case 'WeakSet':
return TargetType.COLLECTION
default:
return TargetType.INVALID
}
}
const enum TargetType {
INVALID = 0,
COMMON = 1,
COLLECTION = 2
}
这里对于3.0有一些改变,3.0是直接判断是否是可以观察的值类型,并没有区分COMMON类型与COLLECTION类型。
总结
reactive 是做为整个响应式的入口,负责处理目标对象是否可观察以及是否已被观察的逻辑,最后使用 Proxy 进行目标对象的代理,Proxy 重点的逻辑处理在 Handlers ,下面我们会介绍collectionHandlers与baseHandlers,并逐步对于前置知识进行补充
更多推荐
所有评论(0)