Vue3系列 - 依赖收集与更新机制

8 天前(已编辑)
/
2

Vue3系列 - 依赖收集与更新机制

依赖收集与更新机制

Vue的响应式系统核心在于依赖收集和更新通知机制,这是通过Dep类实现的。让我们深入了解Vue2.7中的依赖收集与更新机制。

Dep类的作用

Dep类是Vue响应式系统的核心,它负责:

  1. 收集依赖(订阅者,通常是Watcher实例)
  2. 在数据变化时通知这些依赖更新

在Vue2.7中,Dep类的使用可以在customRef的实现中看到:

export function customRef(factory) {
  const dep = new Dep()
  const { get, set } = factory(
    () => {
      if (__DEV__) {
        dep.depend({
          target: ref,
          type: TrackOpTypes.GET,
          key: 'value'
        })
      } else {
        dep.depend()
      }
    },
    () => {
      if (__DEV__) {
        dep.notify({
          target: ref,
          type: TriggerOpTypes.SET,
          key: 'value'
        })
      } else {
        dep.notify()
      }
    }
  )
  // ...
}

依赖收集过程

依赖收集发生在数据被访问(getter)时:

  1. 当组件渲染或计算属性计算时,会创建一个Watcher实例
  2. Watcher将自己设置为当前的依赖收集目标(通过pushTarget
  3. 访问响应式数据的getter时,调用dep.depend()将当前Watcher添加到依赖列表
  4. 渲染或计算完成后,恢复之前的依赖收集目标(通过popTarget

更新通知过程

更新通知发生在数据被修改(setter)时:

  1. 当响应式数据的值被修改时,触发setter
  2. setter调用dep.notify()通知所有依赖
  3. 每个Watcher接收到通知后,根据自己的配置决定如何更新(同步或异步)
  4. 对于渲染Watcher,最终会调用组件的重新渲染

在setup中的依赖收集

setup函数执行过程中,Vue也使用了依赖收集机制:

export function initSetup(vm) {
  // ...
  if (setup) {
    // ...
    setCurrentInstance(vm)
    pushTarget() // 设置依赖收集目标
    const setupResult = invokeWithErrorHandling(
      setup,
      null,
      [vm._props || shallowReactive({}), ctx],
      vm,
      `setup`
    )
    popTarget() // 恢复之前的依赖收集目标
    setCurrentInstance()
    // ...
  }
}

这确保了在setup函数中访问的响应式数据能够正确地收集依赖。

调试依赖关系

Vue3引入了onRenderTrackedonRenderTriggered钩子,帮助开发者调试依赖关系:

const Comp = {
  setup() {
    onRenderTracked((event) => {
      console.log('依赖被追踪', event)
    })
    onRenderTriggered((event) => {
      console.log('更新被触发', event)
    })
    // ...
  }
}

总结

依赖收集与更新机制是Vue响应式系统的核心。通过Dep类,Vue实现了数据与使用数据的地方(如组件渲染、计算属性)之间的连接。理解这一机制,有助于我们更好地理解Vue的响应式原理,解决响应式相关的问题,并编写更高效的Vue应用。

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...