Vue2底层执行逻辑

梳理Vue2底层执行流程

Vue里面有几个比较核心的部分:全局Api的实现,MVVM、双向绑定的实现,控制视图渲染的Watcher和异步更新队列(nexTick)
(TODO:虚拟DOM是在什么时候加入的,生命周期函数何时执行)

初始化

Vue在初始化的时候,会进行一系列的混入,包括

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Vue原型绑定_init方法
initMixin(Vue)

/* 处理和数据相关的api和属性
* 原型绑定$data、对数据做代理,指向_data
* 原型绑定$props、对数据代理,指向_props
* 原型绑定$set、$watch、$delete
*/
stateMixin(Vue)

/* 处理事件相关的api
* 原型绑定$on、$off、$once、$emit
*/
eventsMixin(Vue)

/* 原型绑定生命周期相关的api
* 原型绑定$forceUpdate
* 原型绑定_update
* 原型绑定$destroy
*/
lifecycleMixin(Vue)

/* 原型绑定渲染相关的api
* 原型绑定$nextTic
* 原型绑定_render
* 原型绑定编译执行所需的简化方法
*/
renderMixin(Vue)

Vue底层通过this._init(options)进行初始化,该方法通过initMixin方法挂载到Vue原型上。在initMixin中,Vue会对传入的options通过mergeOptions方法做合并操作,此处也是为什么不能将子组件的data声明为对象的原型。

流程概述

Vue会通过Observe来递归的对数据进行劫持,通过Object.defineProperty来对每一项属性进行劫持。在劫持完毕后,会对_data进行数据代理,将vm._data.a代理成vm.a,也是通过Object.defineProperty实现的。

初始化的同时会通过对_data设置get方法对watcher进行收集,存入Dep数组。通过设置set方法,当数据变化时,调用dep.notify通知收集的watcher更新视图。

在Vue更新视图时,是以异步的方式更新的,watcher被通知更新后,会执行queryWatcher方法,将自身推入更新队列中,如果同一个 watcher 被多次触发,只会被推入到队列中一次。之后判断是否同步更新,若同步执行,则直接调用flushSchedulerQueue。否则通过nextTick方法,将所有回调进行处理,Vue会针对当前环境进行判断,选择合适的方法将任务添加到微任务队列中(实现异步),将处理过的函数赋值给timerFunc,在nextTick中执行timerFunc

// TODO

作者

徐云飞

发布于

2022-11-22

更新于

2023-02-05

许可协议

评论