在vue的内部封装了大量的api和方法供开发者调用,$mount方法是其中之一:
用法:
vm.$mount( [elementOrSelector] )
参数:
{Element | string} [elementOrSelector]{boolean} [hydrating]
作用:
- 如果
Vue实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。可以使用vm.$mount()手动地挂载一个未挂载的实例。 - 如果没有提供
elementOrSelector参数,模板将被渲染为文档之外的的元素,并且你必须使用原生DOM API把它插入文档中。 - 这个方法返回实例自身,因而可以链式调用其它实例方法。
var mount = Vue.prototype.$mount;
Vue.prototype.$mount = function (el,hydrating) {
el = el && query(el);
if (el === document.body || el === document.documentElement) {
warn(
"Do not mount Vue to <html> or <body> - mount to normal elements instead."
);
return this
}
var options = this.$options;
// resolve template/el and convert to render function
if (!options.render) {
var template = options.template;
if (template) {
if (typeof template === 'string') {
if (template.charAt(0) === '#') {
template = idToTemplate(template);
/* istanbul ignore if */
if (!template) {
warn(
("Template element not found or is empty: " + (options.template)),
this
);
}
}
} else if (template.nodeType) {
template = template.innerHTML;
} else {
{
warn('invalid template option:' + template, this);
}
return this
}
} else if (el) {
template = getOuterHTML(el);
}
if (template) {
if (config.performance && mark) {
mark('compile');
}
var ref = compileToFunctions(template, {
outputSourceRange: "development" !== 'production',
shouldDecodeNewlines: shouldDecodeNewlines,
shouldDecodeNewlinesForHref: shouldDecodeNewlinesForHref,
delimiters: options.delimiters,
comments: options.comments
}, this);
var render = ref.render;
var staticRenderFns = ref.staticRenderFns;
options.render = render;
options.staticRenderFns = staticRenderFns;
if (config.performance && mark) {
mark('compile end');
measure(("vue " + (this._name) + " compile"), 'compile', 'compile end');
}
}
}
return mount.call(this, el, hydrating)
};
从源码中可以看到,在vue的实例上挂$mount方法之前,做了一次缓存$mount。这是因为vue的俩个版本造成的,还记得吗,一个是完整版,一个是运行时版本,他们的区别就是有没有模版编译,所以,$mount也就有两个版本,最开始的缓存就是为了,缓存运行时的$mount。下面我们来细看$mount内部是怎么实现的。
从代码中可以看到,该函数可大致分为三部分:
- 根据传入的
el参数获取DOM元素; - 在用户没有手写
render函数的情况下获取传入的模板template; - 将获取到的
template编译成render函数;
首先,根据传入的el获取dom元素,并判断其不是body或者html,这是因为body或者html替换后会破坏html文档结构。
其次,在用户没有手写render函数的情况下获取传入的模板template。
首先获取用户传入的template选项赋给变量template,如果变量template存在,则接着判断如果template是字符串并且以##开头,则认为template是id选择符,则调用idToTemplate函数获取到选择符对应的DOM元素的innerHTML作为模板。如果template不是字符串,那就判断它是不是一个DOM元素,如果是,则使用该DOM元素的innerHTML作为模板,如果既不是字符串,也不是DOM元素,此时会抛出警告:提示用户template选项无效。如果变量template不存在,表明用户没有传入template选项,则根据传入的el参数调用getOuterHTML函数获取外部模板,不管是从内部的template选项中获取模板,还是从外部获取模板,总之就是要获取到用户传入的模板内容,有了模板内容接下来才能将模板编译成渲染函数。获取到模板之后,接下来要做的事就是将其编译成渲染函数,把模板编译成渲染函数是在compileToFunctions函数中进行的,该函数接收待编译的模板字符串和编译选项作为参数,返回一个对象,对象里面的render属性即是编译好的渲染函数,最后将渲染函数设置到$options上。
这就是$mount函数的实现过程。
895

被折叠的 条评论
为什么被折叠?



