步骤一:
reactive 函数在 packages/reactivity/src/reactive.ts 文件下:
export function reactive(target: object) {
// if trying to observe a readonly proxy, return the readonly version.
if (isReadonly(target)) {
return target
}
return createReactiveObject(
target,
false,
mutableHandlers,
mutableCollectionHandlers,
reactiveMap
)
}
reactive 函数实际执行的是 createReactiveObject 方法,而 target 参数就是我们传进来的对象。
步骤二:
createReactiveObject 函数,该函数在 packages/reactivity/src/reactive.ts 文件下:
function createReactiveObject(
target: Target,
isReadonly: boolean,
baseHandlers: ProxyHandler<any>,
collectionHandlers: ProxyHandler<any>,
proxyMap: WeakMap<Target, any>
) {
// 省略
// target already has corresponding Proxy
// 缓存中读取 存在则直接返回
const existingProxy = proxyMap.get(target)
if (existingProxy) {
return existingProxy
}
// 省略
// 这里的 baseHandlers 参数 就是传进来的 mutableHandlers
const proxy = new Proxy(
target,
targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers
)
// 设置缓存
proxyMap.set(target, proxy)
// 返回 proxy 实例对象
return proxy
}
createReactiveObject 函数做了 proxyMap 缓存处理,最终返回一个 proxy 实例对象。new Proxy 这段代码,第一个参数 target 为传进来的对象,即 { name: 'x x x', age: 18 },第二个 baseHandlers 参数即传入的 mutableHandlers 对象,
步骤三:
mutableHandlers对象定义在packages/reactivity/src/baseHandlers.ts中
export const mutableHandlers: ProxyHandler<object> = {
get,
set,
deleteProperty,
has,
ownKeys
}
该对象定义了get、set方法,对传入的数据进行依赖收集和依赖触发。
总结:ractive函数执行完毕,obj得到一个proxy的实例对象。接着又执行effect方法。
步骤四:
effect方法定义在packages/reactivity/src/effect.ts文件:
export function effect<T = any>(
fn: () => T,
options?: ReactiveEffectOptions
): ReactiveEffectRunner {
if ((fn as ReactiveEffectRunner).effect) {
fn = (fn as ReactiveEffectRunner).effect.fn
}
// 创建 ReactiveEffect 实例
const _effect = new ReactiveEffect(fn)
// 省略
if (!options || !options.lazy) {
// 执行 ReactiveEffect 中的 run 方法
_effect.run()
}
// 省略
}
effect函数先声明一个构造函数ReactiveEffect的实例对象_effect,然后执行构造函数中的run 方法
总结:
第一部分:
-
reactive函数实际执行了createReactiveObject方法。 -
createReactiveObject函数做了proxyMap缓存处理,返回一个proxy实例对象。 -
new proxy传两个参数,第一个是target,即为传进来的对象,第二个是baseHandlers参数,即传入的mutableHandlers对象。 -
mutableHandlers对象定义了get、set、has等方法,对传入的数据进行依赖收集和依赖触发。get方法实际执行了createGetter方法,该方法中track函数来进行依赖收集,set方法实际执行了createSetter方法,该方法中trigger进行依赖触发。
第二部分:reactive 函数执行完毕,obj 得到了一个 proxy 的实例对象。接着又执行 effect 方法
-
effect函数声明一个构造函数ReactiveEffect的实例对象_effect,执行构造函数中的run方法 -
ReactiveEffect做了两件事,第一是在run函数中给avtiveEffect赋值,第二是执行fn函数。 -
执行fn函数,就会触发obj的get方法,就会激活
track方法,构建WeakMap即targetMap对象,从而完成指定对象指定属性到effect的依赖收集的工作。 -
此时已经完成了一个依赖收集,之后进行依赖触发
setter。 -
set方法实际执行了createSetter方法,然后触发trigger函数进行依赖触发。 -
trigger函数中首先或从之前targetMap依赖收集的对象中获取,根据key获取到effect,然后执行fn函数,从而完成一个依赖触发的过程。
reactive 缺陷:
-
一是解构后不支持响应性
-
二是不支持基本类型,只能是对象