《Vue进阶教程》第十四课:改进桶布局

打印 上一主题 下一主题

主题 1052|帖子 1052|积分 3156

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
 往期内容:

《Vue进阶教程》第三课:Vue相应式原理
《Vue进阶教程》第四课:reactive()函数详解
《Vue进阶教程》第五课:ref()函数详解(重点)
《Vue进阶教程》第六课:computed()函数详解(上)
《Vue进阶教程》第七课:computed()函数详解(下)
《Vue进阶教程》第八课:watch()函数的基本利用
《Vue进阶教程》第九课:watch()函数的高级利用
《Vue进阶教程》第十课:别的函数
《Vue进阶教程》第十一课:相应式系统先容
《Vue进阶教程》第十二课:实现一对多
《Vue进阶教程》第十三课:实现依赖收集
一、改进桶布局

看起来现在可以主动收集依赖. 但是依然解决不了差别的属性对应差别的副作用函数集合这个问题.
因此, 我们需要改进桶布局
将桶改造成一个Map映射表, 差别的属性对应差别的Set集合


示例
reactive.js
  1. // 定义一个副作用函数桶, 存放所有的副作用函数. 每个元素都是一个副作用函数
  2. const bucket = new Map() // 修改 [name: Set(fn, fn), age: Set(fn, fn)]
  3. // 定义一个全局变量, 保存当前正在执行的副作用函数
  4. let activeEffect = null
  5. function isObject(value) {
  6.   return typeof value === 'object' && value !== null
  7. }
  8. // 收集依赖
  9. function track(target, key) {
  10.   if (!activeEffect) return
  11.   
  12.   let depSet = bucket.get(key)
  13.   if (!depSet) {
  14.     depSet = new Set()
  15.     bucket.set(key, depSet)
  16.   }
  17.   
  18.   // 只有activeEffect有值时(保存的副作用函数), 才添加到桶中
  19.   depSet.add(activeEffect)
  20. }
  21. function trigger(target, key) {
  22.   // 从副作用函数桶中依次取出每一个元素(副作用函数)执行
  23.   let depSet = bucket.get(key)
  24.   if (depSet) {
  25.     depSet.forEach((fn) => fn())
  26.   }
  27. }
  28. /**
  29. * 创建响应式数据
  30. *  @param [object]: 普通对象
  31. *  @return [Proxy]: 代理对象
  32. */
  33. function reactive(data) {
  34.   if (!isObject(data)) return
  35.   
  36.   return new Proxy(data, {
  37.     get(target, key) {
  38.       // 在get操作时, 收集依赖
  39.       track(target, key)
  40.       
  41.       return target[key]
  42.     },
  43.     set(target, key, value) {
  44.       target[key] = value
  45.       // 在set操作时, 触发副作用重新执行
  46.       trigger(target, key)
  47.       return true
  48.     },
  49.   })
  50. }
  51. /**
  52. * 注册副作用函数
  53. *  @param [function]: 需要注册的 副作用函数
  54. */
  55. function effect(fn) {
  56.   if (typeof fn !== 'function') return
  57.   
  58.   // 记录正在执行的副作用函数
  59.   activeEffect = fn
  60.   // 调用副作用函数
  61.   fn()
  62.   // 重置全局变量
  63.   activeEffect = null
  64. }
复制代码
至此, 我们通过改进桶布局, 可以区分同一个代理对象的差别的属性
二、进一步改进桶布局

回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

郭卫东

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表