# vue梳理
- 执行 Vue.prototype._init 方法,初始化this.data,this.props, 执行钩子函数breforeCreate,observe data,代理data,props,执行钩子函数create
- 调用 mount方法,如果没有render方法,这里会生成render方法
- mount 会调用 mountComponent, 创建一个watcher
updateComponent = () => {
vm._update(vm._render(), hydrating)
}
new Watcher(vm, updateComponent, noop, {
before () {
if (vm._isMounted) {
callHook(vm, 'beforeUpdate')
}
}
}, true)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
Watcher 在这里起到两个作用,一个是初始化的时候会执行回调函数, 另一个是当 vm 实例中的监测的数据发生变化的时候执行回调函数
# render
- Vue 的 _render 方法是实例的一个私有方法,它用来把实例渲染成一个虚拟 Node
- vm._render 最终是通过执行 createElement 方法并返回的是 vnode,它是一个虚拟 Node
# update
_update 的核心就是调用 vm.patch 方法
# 首次渲染和更新
new Watcher 执行构造函数 -> 执行get() -> pushTarget(this)把watcher实例压栈,继续执行this.getter.call(vm, vm),也就是执行updateComponent,vm._render() 会生成vnode,会对vm有数据访问,触发对象的getter,对象有__ob__代表是否有监听,对象的每一个值的getter都有个dep,在触发 getter 的时候会调用 dep.depend() 方法,也就会执行 Dep.target.addDep(this),watcher中dep.addSub(this),dep和watcher建立联系。执行get()最后会popTarget()
数据更新的时候,调用setter -> dep.notify() -> subs[i].update() 也就是watcher执行update() -> queueWatcher(this) -> watcher.run() -> 执行get() -> 执行updateComponent
# 编译
- parse: 解析模板字符串生成AST树
- optimize: 优化语法树,把一些 AST 节点优化成静态节点,可以在patch的过程跳过对他们的比对
- codegen: AST树生成Vue的render渲染函数
# nextTick
- queueWatcher(this)实际上是用nextTick(flushSchedulerQueue),异步执行。
- nextTick 是先用微任务,再用宏任务,if else else -> promise.then -> MutationObserver -> setImmediate -> setTimeout
- callbacks数组添加回调函数,根据事件执行顺序(微任务,宏任务)执行callbacks里面的回调函数
# Vue.set
var methodsToPatch = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
];
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
数组重写,先执行原来的方法,push,unshift,splice这三个新增的方法拿到新增的对象,然后重新observe,并且ob.dep.notify()