Vue3响应系统流程概览

65 阅读2分钟

最近读了霍春阳《Vue.js设计与实现》,为了方便以后回顾,根据自己的理解简单整理了一下。

  1. 响应系统
  2. 渲染器
  3. 组件化
  4. 编译器

以上是Vue里面几个核心模块,本篇主要针对响应系统进行了整理

响应系统 响应系统是Vue最重要的一个模块,核心主要两个概念

  • 响应式数据
  • 副作用函数

副作用函数是指会产生副作用的函数,就是该函数的执行的结果会对其他函数的执行结果产生影响。

响应数据的实现在v3里面依赖于代理对象proxy

响应式系统的工作流程是,在读取数据时,收集该数据对应的副作用函数,在设置时执行收集的副作用函数

响应式系统整体流程的实现解决了以下问题。

  1. 对象没有引用时,确保垃圾回收机制的执行。
  2. 函数内部存在三元表达式时,避免出现不必要的更新。
  3. 当副作用函数发生嵌套时,内存副作用函数的执行会对activeEffect产生覆盖。
  4. 当数据出现自增的情况时,触发副作用函数递归调用
  5. 调度器的实现
  6. computed计算属性的实现
  7. watch的实现

对于响应的实现部分,又分为非原始值的响应和原始值的响应 非原始值响应包含

  1. Object

    对属性的读取操作通过proxy,对for...in操作则需要对ownKeys进行拦截

    更合理的触发响应,比如对value相同的赋值屏蔽触发等

    配置深/浅响应,深/浅只读

  2. 数组

    数组是一个虽然异质对象,但是除了[[DefineOwnProperty]]与常规对象不同,其他都一样,所以代理对象的大部分方法都能用,比如通过索引设置或者读取值时,就能被对象的get/set拦截。但是数组通过索引修改值的操作可能会触发长度的变化,所以当通过索引修改数组时,不仅需要触发get属性的副作用函数,还需要触发length属性的副作用函数。

  3. Set和Map

    Set和Map有自己的属性和方法,与普通对象不同。需要对方法进行覆写,在覆写方法里面处理副作用的响应

原始值响应包含

  1. Boolean
  2. Number
  3. BigInt
  4. String
  5. Symbol
  6. undefined
  7. null

proxy无法对原始值进行响应,需要使用对象进行包裹,间接实现原始值的响应