响应式原理二:响应式依赖收集
一、响应式依赖收集
- 依赖收集机制:
- 1.1. 存储结构:使用数组
reactiveFns
存储所有依赖函数 - 1.2. 注册函数:通过
watchFn函数
将依赖函数注册到数组中 - 1.3. 自动执行:注册时会立即执行一次函数,确保初始状态正确
- 示例代码如下:
// 设置一个专门执行响应式函数的一个函数 const reactiveFns = [] function watchFn (fn) {// 把所有依赖的东西,统一收集到一个数组中(reactiveFns), 方便进行管理reactiveFns.push(fn)// 传入函数后立即执行一次,类似watchEffect()fn() }
- 1.1. 存储结构:使用数组
- 应用示例:
- 2.1. 当对象属性
obj.name
或obj.age
变化时 - 2.2. 自动执行所有依赖这些属性的函数(如
foo()
和bar()
) - 2.3.通过
遍历reactiveFns数组统一执行所有依赖函数
-
const obj = {name: 'why',age: 18}// 设置一个专门执行响应式函数的一个函数const reactiveFns = []function watchFn (fn) {// 把所有依赖的东西,统一收集到一个数组中(reactiveFns), 方便进行管理reactiveFns.push(fn)// 传入函数后立即执行一次,类似watchEffect()fn()}watchFn(function foo () {console.log('foo: ', obj.name);console.log('foo: ', obj.age);console.log('foo function');})watchFn(function bar () {console.log('bar: ', obj.name + ' hello');console.log('bar: ', obj.age + 10);console.log('bar function');})// 修改obj的属性console.log('name发生变化时----------------------------------------');obj.name = 'kobe'// 当依赖发生变化时,会执行对应的响应式函数reactiveFns.forEach(fn => {fn()})
- 2.1. 当对象属性
- 执行流程:
- 3.1. 属性修改触发更新
- 3.2. 从依赖数组中取出所有相关函数
- 3.3.依次执行每个依赖函数
- 设计特点:
- 4.1.
手动收集
:目前需要显式调用watchFn
注册依赖函数 - 4.2.
统一管理
:所有依赖函数集中存储在数组中便于统一触发 - 4.3.
自动执行
:注册时立即执行确保初始状态,变化时再次执行更新状态
- 4.1.
watchFn
与Vue
的关系:- 5.1. 类似
Vue3的watchEffect机制
- 5.2. 区别在于
当前实现是手动收集依赖
- 5.3.
后续会优化为自动依赖收集
- 5.1. 类似
小结
知识点 | 核心内容 | 易混淆点/难点 | 代码示例/关键实现 |
---|---|---|---|
响应式机制原理 | 通过监听对象属性变化触发依赖函数重新执行 | 手动收集依赖 vs 自动收集依赖 | watchFn(fn) 函数封装与依赖数组管理 |
依赖收集实现 | 将依赖函数统一存入 reactiveFns 数组,属性变化时遍历执行 | 依赖函数初次执行时机(立即执行 vs 延迟执行) | reactiveFns.push(fn); fn() |
WatchFn 设计 | 函数注册机制:标记需响应式的函数并自动执行一次 | 非响应式函数误注册问题(后续优化点) | watchFn(() => { console.log(obj.name) }) |
响应式触发流程 | 1. 修改属性值 → 2. 从依赖数组提取函数 → 3. 批量执行 | 多属性依赖时的执行效率(未优化) | obj.name = “copy” 触发 foo() 和 bar() |
与 WatchEffect 对比 | 类似 Vue 的 watchEffect,但依赖需手动声明 | 自动依赖追踪的实现差异(当前未实现) | 无自动依赖关系分析 |