new Vue()的过程
new Vue()的大致流程
new Vue() => _init() => $mount() => mountComponent() => new Watcher() => updateComponent() => render() => _update()
用户调用 new Vue(options) 实例化 Vue,Vue 在 _init 方法中初始化相关字段和事件,最重要的,建立起响应式系统,Vue 实例的后续运行重度依赖于此响应式系统。Vue 会新建一个【观察者】,该观察者在创建时会执行 update 方法首次渲染视图,包含 Vue 指令的模板会被替换成编译后的朴素 HTML。Vue 会遍历传入的 data 选项,通过 Object.defineProperty 设置 setter 和 getter 将其变成【被观察对象】。当 data 的数据发生变化时,被观察对象就会通知观察者,观察者就会再次调用 update 方法打补丁式地更新视图。
简版过程
=> _init() : Vue构造函数constructor()中进行初始化:主要进行
- initLifecircle :
$parent /$root / $children
- initEvents: 事件监听
- initRender:
slot / $createElment()
- callHook(vm, 'beforeCreate'):组件创建之前的钩子
- initInjections: 注入祖辈传递的数据
- initState: ☆ 组件数据初始化,包括 props、data、methods、computed、watch。 数据响应式:data中一个key就一个Dep实例
- initProvide:在data等之后再进行输出 provide
- callHook(vm, 'created'): create生命周期完成
=> $mount(): 初始化完成之后,进行挂载。如果我当前执行的是编辑器的版本,用的模板字符串的方式去申明的模板,那我就需要进行编译
=> mountComponent():编译完成,就会调用mountComponent方法。这个方法中主要做两件事:1. 申明一个updateComponent方法。 2. 创建一个Watcher实例,和当前组件之间产生一个1对1的关系,这个watcher需要初始化或者更新updateComponent这个方法
-
=> new Watcher():
是在数据初始化之后,即在created钩子函数之后,mounted钩子函数之前进行Watcher实例化。
跟当前组件产生1对1的关系。这个watcher实例的作用是:初始化或者更新 updateComponent这个函数。在初始化的时候会执行updateComponent函数, 当watcher管理的数据发生变化的时候,updateComponent方法就会再次执行。由于这个wathcer关联的是当前的这个组件实例,这个组件内部的任何值发生变化,这个updateComponent方法都会执行。
-
=> updateComponent():
- => render(): 获取虚拟Dom
- => _update():转为真实dom:初始化el,或者通过
__patch__
(即diff算法)进行更新
updateComponent这个方法执行的时候,会先执行render方法,得到虚拟dom,再把vdom作为参数传给_update,让 _update执行比对。
如果_update首次进行比对的时候,显然,首次vdom是不存在的,所以进行初始化操作,批量创建,直接追加。
如果是后期的更新操作,由于有新旧vdom,就要进行比对,进行diff操作。