在不同的Vue.js构建版本中,vm.$mount的表现是不一样的。完整版和只包含运行时版本之间的差异在于是否有编译器。
在完整版中,vm.$mount会先检查template或el选项提供的模板是否已经转换成了渲染函数,如果没有则将模板编译成渲染函数。
而在只包含运行时的版本中,vm.$mount是没有编译模板的步骤的,它默认实例上已经有渲染函数了,如果没有它会自己设置一个。
1、只包含运行时版本的vm.$mount
Vue.prototype.$mount = function (
el?: string | Element,
hydrating?: boolean
): Component {
el = el && inBrowser ? query(el) : undefined
return mountComponent(this, el, hydrating)
}
vm.$mount函数内的逻辑非常简单,通过el获取DOM元素,然后调用mountComponent函数将Vue实例挂载到DOM元素上。
mountComponent函数:
export function mountComponent (
vm: Component,
el: ?Element,
hydrating?: boolean
): Component {
vm.$el = el
//判断实例上是否有渲染函数
if (!vm.$options.render) {
//设置一个默认的渲染函数
vm.$options.render = createEmptyVNode
//控制台打印警告
if (process.env.NODE_ENV !== 'production') {
/* istanbul ignore if */
if ((vm.$options.template && vm.$options.template.charAt(0) !== '#') ||
vm.$options.el || el) {
warn(
'You are using the runtime-only build of Vue where the template ' +
'compiler is not available. Either pre-compile the templates into ' +
'render functions, or use the compiler-included build.',
vm
)
} else {
warn(
'Failed to mount component: template or render function not defined.',
vm
)
}
}
}
//触发“beforeMount”生命周期钩子
callHook(vm, 'beforeMount')
let updateComponent
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
updateComponent = () => {
const name = vm._name
const id = vm._uid
const startTag = `vue-perf-start:${
id}`
const endTag = `vue-perf-end:${
id}`
mark(startTag)
const vnode = vm._render()
mark(endTag)
measure(`vue ${
name} render`, startTag, endTag)
mark(startTag)
vm._update(vnode, hydrating)
mark(endTag)
measure(`vue ${
name} patch`, startTag, endTag