Vue源码解析:Watcher 类

Watcher 分为三种:

  • Computed Watcher;
  • 用户 Watcher (监听器);
  • 渲染 Watcher

渲染 Watcher 的创建时机:src/core/instance/lifecycle.js。
渲染 watcher 创建的位置: lifecycle.js 的 mountComponent 函数中。
Watcher 是没有静态方法的,因为 $watch 方法中要使用 Vue 的实例。创建顺序:计算属性 Watcher、用户 Watcher (监听器)、渲染 Watcher

Watcher 创建的工作流程:

        首先 Watcher 的构造函数初始化,处理 expOrFn (渲染 watcher 和监听器处理不同)。
=>调用 this.get(),它里面调用 pushTarget() 然后 this.getter.call(vm, vm) (对于渲染 watcher 调用 updateComponent),如果是用户 watcher 会获取属性的值 (触发 get 操作)。
        当数据更新的时候,dep 中调用 notify() 方法。
=>notify() 中调用 watcher 的 update() 方法。
=> 在update() 中调用 queueWatcher()。
=> queueWatcher() 是一个核心方法,去除重复操作,调用 flushSchedulerQueue() 刷新队列并执行 watcher。
并且在flushSchedulerQueue() 中对 watcher 排序,遍历所有 watcher,如果有 before,触发生命周期的钩子函数 beforeUpdate,执行 watcher.run(),它内部调用 this.get(),然后调用 this.cb() (渲染 watcher 的 cb 是 noop)
整个流程结束。

查看渲染 watcher 的执行过程

        当有数据发生更新时:

  • 首先defineReactive 的 set 方法中调用 dep.notify()。
  • 然后调用 watcher 的 update()
  • 再调用 queueWatcher(),把 watch 存入队列,如果已经存入,不重复添加
  • 接着循环调用 flushSchedulerQueue(),并通过 nextTick(),在消息循环结束之前时调用 flushSchedulerQueue()。
  • 最后调用 watcher.run():通过调用 watcher.get() 获取最新值。如果是渲染 watcher 结束,如果是用户 watcher,调用 this.cb()。
            以上,整个流程结束。

猜你喜欢

转载自blog.csdn.net/weixin_40599109/article/details/108287024
今日推荐