Vue3 对于响应式数据,不再像 Vue2 中那样递归对所有的子数据进行响应式定义了,而是再获取到深层数据的时候再去利用 reactive 进一步定义响应式, 这样设计的一大原因就是让业务代码可以更加高内聚低耦合,这对于大量数据的初始化场景来说收益会非常大。

ref

refreactive 两个函数都是用于监听数据修改,实现了数据绑定。 两者的区别在于 ref 是用于监听原始值的。 因为 js 原始值不能引用内存地址,就算进行了更改也没有办法追踪数据状态,因此ref可以将其包装成一个对象,这样就可以获取到这个变量的引用,监听修改。 ref 只有一个 value 属性。
通过使用 ref 监听变量修改,使用 watch 订阅通知。

reactive

有了 ref 的实现思路,实现 reactive 就很简单了。 ref 只是对原始类型进行了一次包装,而reactive 需要实现对象的遍历监听以及属性增删的监听。如果属性是对象,就返回一个 reactive 包装的对象,递归遍历。由于对象有多个属性,每个属性都有对应的订阅列表,因此容器 subMap 的数据结构为 WeakMap

effect

effect是watcheffect和watch的统称。effect其实就是一个依赖收集函数,在它内部访问了响应式数据,响应式数据就会把这个effect函数作为依赖收集起来,下次响应式数据改了就触发它重新执行。一般与reactive连着使用。
举个例子:

  1. // 响应式数据
  2. const data = reactive({ count: 0 })
  3. // 依赖收集
  4. watcheffect(() => console.log(data.count))
  5. // 触发上面的effect重新执行
  6. data.count ++

data是reactive创建的一个响应式数据。effect传入的函数因为内部访问到它上面的属性count了,
所以形成了一个count -> effect的依赖。下次count改变了,这个effect就会重新执行。

computed

computed是Vue中的计算属性,在一个计算属性里可以完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回一个结果就可以。计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。其实computed原理很简单生成一个effect函数,然后返回一个对象,这个对象的getter会执行对应的计算属性函数。

  1. // 1. 响应式数据
  2. const data = reactive({ count: 0 })
  3. // 2. 计算属性
  4. const plusOne = computed(() => data.count + 1)
  5. // 3. 依赖收集
  6. effect(() => console.log(plusOne.value))
  7. // 4. 触发上面的effect重新执行
  8. data.count ++

其实,computed其实也是一个effect,是一个双向依赖收集的运用。

暗号:我要报全栈

谢谢紫薯老师这一个月的教导,等我消化了这个课程,我就去报全栈。