Vue3 响应式解析

297 阅读2分钟

核心就是任务和响应式对象的关系,本文姑且称作 job 和 reactiveObj 的关系

job 与 reactiveObj 是什么?

举几个 job 的栗子
  • redner job
  • computed job
  • watch job
举几个 reactiveObj 的栗子
  • data 函数创建的对象

    组件实例初始化阶段,运行 data 函数,并使用 proxy 劫持生成的代理对象,本文称其为 proxyData

  • computed 的方法创建的内置对象

    Vue 会在内部为 computed 属性函数创建一个对象,其只有一个属性值 value,本文称其为 computedData,再在组件实例上定义一个与计算函数同名的属性,其 get 函数即为 () => computedData.value。

  • props 传入的所有props创建的的一个对象

job 与 reactiveObj 有什么关系?

生成 job 时,使用 track 方法将 job 与 reactiveObj 对象的属性建立依赖关系。reactiveObj 属性值改变时,使用 trigger 方法执行被依赖的 job,并重新建立依赖。

Vue 利用 Proxy 或者 Object.defineProperty 在获取或改变 reactiveObj 属性值时做依赖的相关操作

举几个例子

render job & proxyData 属性值

render job,在挂载首次渲染时,会立即执行,在渲染阶段中使用到 proxyData 属性时,触发其 get 函数建立依赖。

在 proxyData 属性改变时,触发其 set 函数触发 render job,因为 render job 生成时有配置 scheduler 为 queueJob,所以渲染任务会在微任务队列中执行。

render job & computedData 的 value 属性

假设 render job 使用了某个 computedData, 其计算函数又使用了 proxyData。

挂载时立即执行 render job,render job 获取 computedData,生成 computed job,computed job 执行计算函数又将 computed job 和 proxyData 建立依赖,然后 computedData 和 render job 主动建立依赖。

proxyData 改变时,触发 computed job,computed job 手动触发 render job ,render job,又重新获取 computedData,开始一轮新的依赖绑定流程。