共计 1619 个字符,预计需要花费 5 分钟才能阅读完成。
触发更新时 watcher 的执行
- watcher 分为三种,Computed Watcher,用户 Watcher 侦听器,渲染 Watcher
- 前两种 initState 时初始化
- 渲染 watcher 在 core/instance/lifecycle.js 中 mountComponent,后执行
- 当调用 dep.notify 时,会对 watcher 排序,而后顺次更新 watcher.update
- 对于不同类型 watcher,update 解决形式不同
- 渲染 watcher 会判断 以后组件 watcher 是否放入队列中,未放入 则找到地位插入到队列中
-
调用 flushSchedulerQueue 办法
- 先更新父组件后更新子组件(父组件先创立)
- 用户 watchers 在渲染 watcher 之前运行,(用户或计算属性在 initState 中创立,在 mountComponent 之前)
- 如果一个组件在父组件执行期间被销毁,则跳过以后组件
- 遍历队列中的 watcher,调用 watcher.run()
- run 办法内 调用 get 办法,get 办法调用 了 this.getter.call(vm, vm)
- this.getter 就是 updateComponent 办法
- 更新完结后重置状态
-
调用 activated,updated 两个钩子
notify () { // copy const subs = this.subs.slice() if (process.env.NODE_ENV !== 'production' && !config.async) { // 按 watcher 的创立程序排序 subs.sort((a, b) => a.id - b.id) } // 调用 watcher 的 更新 for (let i = 0, l = subs.length; i < l; i++) {subs[i].update()} } update () { // 三种 watcher update 渲染 watcher 走 else if (this.lazy) {this.dirty = true} else if (this.sync) {this.run() } else {queueWatcher(this) } } export function queueWatcher (watcher: Watcher) { const id = watcher.id // has 是个对象,避免 watcher 被反复解决 if (has[id] == null) {has[id] = true // flushing = true 示意 watcher 对象正在被解决 // 把 watcher 放入队列中 if (!flushing) {queue.push(watcher) } else { let i = queue.length - 1 // 队列未解决完,从后向前取 watcher 和以后组件 watcher 比拟,确定 i while (i > index && queue[i].id > watcher.id) {i--} // 把组件 watcher 插入对应地位 queue.splice(i + 1, 0, watcher) } // waiting = true 示意 以后队列正在执行 if (!waiting) { waiting = true if (process.env.NODE_ENV !== 'production' && !config.async) {// 遍历所有 watcher, 调用 watcher.run() flushSchedulerQueue() return } // 生产环境会传入 nextTick,nextTick(flushSchedulerQueue) } } } function flushSchedulerQueue () { ... // 把 watcher 插入队列 // 遍历队列内的 watcher 执行 run watcher.run() ... } run () { ... this.get() // this 指 watcher ... } get () {pushTarget(this) ... // this.getter 为 updateComponent value = this.getter.call(vm,vm) }
正文完