返回
Vue 源码剖析:揭秘 Vue 实例挂载全过程
前端
2023-12-11 02:14:47
当我们使用 Vue 时,总是会创建一个 Vue 实例,那么在创建 Vue 实例时,内部发生了什么?我们今天就来窥探 Vue 源码,看看 Vue 是如何实现实例挂载的。
从 new Vue 对象开始
const vm = new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
}
})
当我们通过 new Vue({})
创建一个 Vue 实例时,首先会调用 Vue 的构造函数。但是,Vue 的构造函数只做了一件事情,就是调用 _init
函数进行初始化。
_init,初始化
_init (options?: Object) {
// Vue.prototype._init 是一个中间层,调用_initOptions传入options
this._initOptions(options)
// 初始化各种属性
this._initScope()
this._initEvents()
// 真正对实例进行观测依赖的函数入口
this._initObservable()
// 对组件进行挂载挂载
this._initDOMHooks()
}
_init
函数做了很多事情,包括:
- 调用
_initOptions
函数,将用户传入的选项与默认选项合并,形成最终的选项。 - 初始化各种属性,如
$el
、$data
、$props
等。 - 初始化事件系统。
- 调用
_initObservable
函数,对实例进行观测依赖的处理。 - 调用
_initDOMHooks
函数,对组件进行挂载挂载。
_initDOMHooks,组件挂载
_initDOMHooks (mounted: Function) {
// this.$el 是真实dom节点
// Vue.compile 是一个全局的渲染函数
this.$el = typeof this.$el === 'string' ? query(this.$el) : this.$el
this._callHook('beforeMount')
// 真正的挂载方法,将虚拟dom挂载到真实dom
this._mount(this.$el, mounted)
this._callHook('mounted')
}
_initDOMHooks
函数主要做了以下几件事:
- 将
$el
属性的值转换为真实 DOM 节点。 - 调用
beforeMount
钩子函数。 - 调用
_mount
函数,将虚拟 DOM 挂载到真实 DOM。 - 调用
mounted
钩子函数。
_mount,虚拟 DOM 挂载
_mount (el: Node | Element, hydrating?: boolean): Component {
// 调用 `_render` 函数生成虚拟dom,虚拟dom就是渲染函数的返回结果
this._vnode = this._render()
// 虚拟dom挂载的入口
this._update(this._vnode, el, hydrating)
}
_mount
函数主要做了以下几件事:
- 调用
_render
函数生成虚拟 DOM。 - 调用
_update
函数,将虚拟 DOM 挂载到真实 DOM。
总结
以上就是 Vue 实例挂载的全过程。通过剖析 Vue 源码,我们了解到 Vue 是如何将虚拟 DOM 挂载到真实 DOM 的。