vue原理分析(四)Vue实例挂载到app上面
今天我们来分析Vue实例的挂载
代码如下:
new Vue({
render: h => h(App),
}).$mount('#app')
new Vue({
render: h => h(App),
}).$mount('#app')
这串代码可以拆分成2句
第一句是创建一个Vue实例
const app = new Vue({ render: h => h(App) })
在上一篇中,我们已经分析了,创建Vue实例实际上是
const app = new Vue({
el: '#root',
template: '<App></App>',
components: {
App
}
})
第二句是将Vue实例挂载在id为app的标签上,这个app标签是在index.html中,大家可以自己找一下
app.$mount('#app')
这里研究下挂载
app.$mount('#app')
app是一个Vue实例,调用了$mount方法,该方法有个入参'#app'
vue.common.dev.js的源码,中文注释是源码解读
Vue.prototype.$mount = function (el, hydrating) {
// 获取el属性,挂载点
el = el && query(el);
/* istanbul ignore if */
// 实例不允许挂载在body或者html标签上
if (el === document.body || el === document.documentElement) {
warn$2(`Do not mount Vue to <html> or <body> - mount to normal elements instead.`);
return this;
}
// options配置项
const options = this.$options;
// resolve template/el and convert to render function
// 如果用户提供了 render 配置项,则直接跳过编译阶段,否则进入编译阶段, 优先级render——> template ——>el
if (!options.render) {
let template = options.template;
// 处理 template 选项
if (template) {
if (typeof template === 'string') {
if (template.charAt(0) === '#') {
// { template: '#app' },template 是一个 id 选择器,则获取该元素的 innerHtml 作为模版
template = idToTemplate(template);
/* istanbul ignore if */
if (!template) {
warn$2(`Template element not found or is empty: ${options.template}`, this);
}
}
}
else if (template.nodeType) {
// template 是一个正常的元素,获取其 innerHtml 作为模版
template = template.innerHTML;
}
else {
{
warn$2('invalid template option:' + template, this);
}
return this;
}
}
else if (el) {
// 设置了 el 选项,获取 el 选择器的 outerHtml 作为模版
// @ts-expect-error
template = getOuterHTML(el);
}
if (template) {
/* istanbul ignore if */
if (config.performance && mark) {
mark('compile');
}
// 编译模版,得到 动态渲染函数和静态渲染函数
const { render, staticRenderFns } = compileToFunctions(template, {
outputSourceRange: true,
shouldDecodeNewlines,
shouldDecodeNewlinesForHref,
// 界定符,默认 {{}}
delimiters: options.delimiters,
// 是否保留注释
comments: options.comments
}, this);
// 将两个渲染函数放到 this.$options 上
options.render = render;
options.staticRenderFns = staticRenderFns;
/* istanbul ignore if */
if (config.performance && mark) {
mark('compile end');
measure(`vue ${this._name} compile`, 'compile', 'compile end');
}
}
}
// 执行挂载,执行的是缓存的$mount
return mount.call(this, el, hydrating);
};