Vue-nextTick

在 Vue 中 nextTick 实际上是一个 microTask(在 2.5 中曾被替换为 macroTask 实现,2.6 中又恢复为 microTask),源码位于 src/core/util/next-tick.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
export function nextTick (cb?: Function, ctx?: Object) {
let _resolve
callbacks.push(() => {
if (cb) {
try {
cb.call(ctx)
} catch (e) {
handleError(e, ctx, 'nextTick')
}
} else if (_resolve) {
_resolve(ctx)
}
})
if (!pending) {
pending = true
timerFunc()
}
// $flow-disable-line
if (!cb && typeof Promise !== 'undefined') {
return new Promise(resolve => {
_resolve = resolve
})
}
}

Vue-computed

computed 与 data 类似,在 init 阶段的 initState 中初始化的:

1
2
3
4
5
6
7
// 遍历 computed,,为子项创建 watcher
watchers[key] = new Watcher(
vm,
getter || noop,
noop,
computedWatcherOptions
)

如果 key 不是 vm 的属性则会调用:

Vue-Vnode

Vnode 是 Vue 内部的核心数据结构,用来描述 DOM 及 Component 和其对应的各种状态,例如:

1
2
3
4
5
6
7
8
9
10
const elementVNode = {
tag: 'div',
data: {
style: {
width: '100px',
height: '100px',
backgroundColor: 'red'
}
}
}

Vnode 的创建

Vue defineReactive

大致执行过程

依赖收集

  1. initState 时,调用 initPropsinitData 等 init 方法,通过 Observer 添加 getter 和 setter。
  2. Observer 中调用 defineReactive 完成响应式对象初始化。
  3. 在 DefineReactive 中设置 getter,并在 getter 中通过 dep.depend() 收集依赖。

建立观察者

  1. mountComponent 时会建立一个 watcher。
  2. 创建 watcher 时触发 updateComponent,从而触发组件依赖元素的 getter。
  3. 触发各个元素 getter 中的依赖收集。Dep.target 设置为当前 watcher。
  4. Dep.target.addDep 会将各个元素依赖添加到当前 watcher。
  5. Dep.target.addDep 调用时也会调用 dep.addSub 将 watcher 添加到 dep 的观察者列表中。

更新

  1. 当修改值时会触发元素的 setter。
  2. 通过 dep.notify() 通知 watcher。
  3. 在 watcher 的 update 中执行更新方法。
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×