在 Vue.js 中,实例挂载的过程主要分为以下几个阶段,从源码的角度来看,可以通过 Vue.prototype._init
函数了解其内部执行流程。整个挂载过程大致包括以下步骤:
1. Vue 实例初始化
在创建 Vue 实例时,执行 new Vue()
时会调用 _init
方法来初始化实例。
- 初始化生命周期:调用
initLifecycle(vm)
函数,初始化与生命周期相关的变量,如$parent
、$children
等。 - 初始化事件:调用
initEvents(vm)
,设置实例的事件系统,如$on
、$emit
等。 - 初始化渲染:调用
initRender(vm)
,初始化与渲染相关的功能,如$createElement
。 - 调用 beforeCreate 钩子:此时触发
beforeCreate
钩子函数,开发者可以在此时执行相关逻辑。 - 初始化依赖注入 (provide/inject):在此阶段处理依赖注入关系。
- 初始化数据 (data, props, computed, methods):调用
initState(vm)
,初始化响应式数据系统,包括data
、props
、computed
和methods
。
2. 调用 created
钩子
在数据初始化之后,Vue 调用 created
钩子函数,用户可以在此时执行与数据相关的逻辑,如 API 请求等。
3. 模板编译阶段
当模板(template
或 render
函数)准备好时,Vue 开始进行模板的编译。
- 查找模板或 render 函数:Vue 检查实例中是否有提供
template
或render
函数,如果没有,会尝试从挂载的元素内提取模板。 - 模板编译为渲染函数:如果提供了
template
,Vue 会将其编译为渲染函数,这一过程通过compileToFunctions
完成。
4. 挂载 DOM
- 挂载阶段的主要函数是
vm.$mount(el)
:根据传入的el
(挂载元素),Vue 将实例挂载到 DOM 上。 - 调用
beforeMount
钩子:在实际 DOM 挂载之前,Vue 触发beforeMount
生命周期钩子函数。 - 执行首次渲染:通过
vm._update
方法,将虚拟 DOM 转换为真实 DOM 并挂载到页面上。
5. 渲染与更新
- 首次渲染:首次渲染时,Vue 会创建一个
Watcher
实例,负责监控响应式数据的变化。 - 调用
mounted
钩子:当 Vue 完成 DOM 挂载后,触发mounted
钩子,此时实例已经完成了初始化和首次渲染。 - 响应式更新:当数据发生变化时,依赖的数据会通过
Watcher
自动触发组件重新渲染,Vue 的虚拟 DOM 会高效地进行差异化更新(Diff 算法)。
总结源码流程:
// Vue.prototype._init 方法执行
Vue.prototype._init = function (options) {
const vm = this;
// 生命周期、事件、渲染等初始化
initLifecycle(vm);
initEvents(vm);
initRender(vm);
// 调用 beforeCreate 钩子
callHook(vm, 'beforeCreate');
// 依赖注入初始化
initInjections(vm);
// 初始化数据
initState(vm);
// 调用 created 钩子
callHook(vm, 'created');
// 判断是否有 el,进行挂载
if (vm.$options.el) {
vm.$mount(vm.$options.el);
}
};
// $mount 负责挂载
Vue.prototype.$mount = function (el) {
const vm = this;
el = document.querySelector(el);
// 模板编译
if (!vm.$options.render) {
let template = vm.$options.template || el.outerHTML;
const { render } = compileToFunctions(template);
vm.$options.render = render;
}
// 挂载 DOM
mountComponent(vm, el);
};
这个流程中,Vue 的生命周期钩子、数据响应式和模板编译都参与其中,确保 Vue 实例能够顺利渲染并进行后续的更新操作。
Vue 实例挂载的重点:
- 生命周期钩子:各个钩子函数如
beforeCreate
、created
、beforeMount
、mounted
在不同阶段执行,给开发者提供了干预点。 - 模板编译与渲染:Vue 的模板编译过程将 HTML 模板转化为渲染函数(
render
),并通过虚拟 DOM 渲染更新。 - 响应式系统:Vue 的数据变化会自动触发 DOM 更新,这是 Vue 响应式核心机制的一部分。
这些源码细节帮助 Vue 实现了灵活、高效的视图更新机制。