马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
往期内容:
《Vue进阶教程》第三课:Vue相应式原理
《Vue进阶教程》第四课:reactive()函数详解
《Vue进阶教程》第五课:ref()函数详解(重点)
《Vue进阶教程》第六课:computed()函数详解(上)
《Vue进阶教程》第七课:computed()函数详解(下)
《Vue进阶教程》第八课:watch()函数的基本利用
《Vue进阶教程》第九课:watch()函数的高级利用
《Vue进阶教程》第十课:别的函数
《Vue进阶教程》第十一课:相应式系统先容
《Vue进阶教程》第十二课:实现一对多
《Vue进阶教程》第十三课:实现依赖收集
一、改进桶布局
看起来现在可以主动收集依赖. 但是依然解决不了差别的属性对应差别的副作用函数集合这个问题.
因此, 我们需要改进桶布局
将桶改造成一个Map映射表, 差别的属性对应差别的Set集合

示例
reactive.js
- // 定义一个副作用函数桶, 存放所有的副作用函数. 每个元素都是一个副作用函数
- const bucket = new Map() // 修改 [name: Set(fn, fn), age: Set(fn, fn)]
- // 定义一个全局变量, 保存当前正在执行的副作用函数
- let activeEffect = null
- function isObject(value) {
- return typeof value === 'object' && value !== null
- }
- // 收集依赖
- function track(target, key) {
- if (!activeEffect) return
-
- let depSet = bucket.get(key)
- if (!depSet) {
- depSet = new Set()
- bucket.set(key, depSet)
- }
-
- // 只有activeEffect有值时(保存的副作用函数), 才添加到桶中
- depSet.add(activeEffect)
- }
- function trigger(target, key) {
- // 从副作用函数桶中依次取出每一个元素(副作用函数)执行
- let depSet = bucket.get(key)
- if (depSet) {
- depSet.forEach((fn) => fn())
- }
- }
- /**
- * 创建响应式数据
- * @param [object]: 普通对象
- * @return [Proxy]: 代理对象
- */
- function reactive(data) {
- if (!isObject(data)) return
-
- return new Proxy(data, {
- get(target, key) {
- // 在get操作时, 收集依赖
- track(target, key)
-
- return target[key]
- },
- set(target, key, value) {
- target[key] = value
- // 在set操作时, 触发副作用重新执行
- trigger(target, key)
- return true
- },
- })
- }
- /**
- * 注册副作用函数
- * @param [function]: 需要注册的 副作用函数
- */
- function effect(fn) {
- if (typeof fn !== 'function') return
-
- // 记录正在执行的副作用函数
- activeEffect = fn
- // 调用副作用函数
- fn()
- // 重置全局变量
- activeEffect = null
- }
复制代码 至此, 我们通过改进桶布局, 可以区分同一个代理对象的差别的属性
二、进一步改进桶布局
|