以下仅为个人见解。
1.大致流程:
- new Vue()时会调用initMixin(Vue)将_init挂载到vue原型上;
- 在_init()中调用$mount()方法($mount()方法也是挂载到vue原型上的)编译template模版,并生成render()函数;
- 挂载到vm上后,会再次调用$mount()并返回调用mountComponet()方法,mountComponet中的updateComponent()方法调用vue原型上的render()和update()方法,最后进行页面渲染
2. Vue.prototype._init
主要初始化proxy拦截器,初始化组件事件监听,初始化渲染方法,初始化依赖注入,初始化数据(props/data/method/computed/watch),初始化provide注入,调用$mount()
// 初始化proxy拦截器
initProxy(vm)
// 初始化组件生命周期标志位
initLifecycle(vm)
// 初始化组件事件侦听
initEvents(vm)
// 初始化渲染方法
initRender(vm)
callHook(vm, 'beforeCreate')
// 初始化依赖注入内容,在初始化data、props之前
initInjections(vm) // resolve injections before data/props
// 初始化props/data/method/computed/watch
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
....
vm.$mount(vm.$options.el)
3. Vue.prototype.$mount()首次调用进行模版编译
1.可以在对象中定义template/render或者直接使用template、el表示元素选择器
2.将template解析ast tree
3.将ast tree转换成render语法字符串
4.生成render方法
template获取过程:
4.生成render()函数后,会挂载到vm上,然后再次调用vue原型上的$mount()方法
此次调用会返回mountComponent()
// public mount method
Vue.prototype.$mount = function (
el?: string | Element,
hydrating?: boolean
): Component {
el = el && inBrowser ? query(el) : undefined
// 渲染组件
return mountComponent(this, el, hydrating)
}
updateComponent(): mountComponent()中调用updateComponent()执行初始化时原型上的_render和_update()方法
// 定义更新函数
updateComponent = () => {
// 实际调⽤是在lifeCycleMixin中定义的_update和renderMixin中定义的_render
vm._update(vm._render(), hydrating)
}
5.Vue.prototype.render方法
主要是生成VNode
6.Vue.prototype.update方法
_update
主要功能是调用patch
,将vnode
转换为真实DOM
,并且更新到页面中
参考:
面试官:Vue实例挂载的过程 | web前端面试 - 面试官系列