参数
el
- 类型:
string | Element - 限制:只在用
new创建实例时生效。 详细:
提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。可以是 CSS 选择器,也可以是一个 HTMLElement 实例。
在实例挂载之后,元素可以用vm.$el访问。
如果在实例化时存在这个选项,实例将立即进入编译过程,否则,需要显式调用vm.$mount()手动开启编译。
提供的元素只能作为挂载点。不同于 Vue 1.x,所有的挂载元素会被 Vue 生成的 DOM 替换。因此不推荐挂载 root 实例到<html>或者<body>上。
如果render函数和template属性都不存在,挂载 DOM 元素的 HTML 会被提取出来用作模板,此时,必须使用 Runtime + Compiler 构建的 Vue 库。template
类型:
string详细:
一个字符串模板作为 Vue 实例的标识使用。模板将会 替换 挂载的元素。挂载元素的内容都将被忽略,除非模板的内容有分发插槽。
如果值以#开始,则它将被用作选择符,并使用匹配元素的 innerHTML 作为模板。常用的技巧是用<script type="x-template">包含模板。
出于安全考虑,你应该只使用你信任的 Vue 模板。避免使用其他人生成的内容作为你的模板。
如果 Vue 选项中包含渲染函数,该模板将被忽略。render
类型:
(createElement: () => VNode) => VNode- 详细:
字符串模板的代替方案,允许你发挥 JavaScript 最大的编程能力。该渲染函数接收一个createElement方法作为第一个参数用来创建VNode。
如果组件是一个函数组件,渲染函数还会接收一个额外的context参数,为没有实例的函数组件提供上下文信息。
Vue 选项中的render函数若存在,则 Vue 构造函数不会从template选项或通过el选项指定的挂载元素中提取出的 HTML 模板编译渲染函数。
对不同构建版本的解释
- 完整版:同时包含编译器和运行时的版本。
- 编译器:用来将模板字符串编译成为 JavaScript 渲染函数的代码。
- 运行时:用来创建 Vue 实例、渲染并处理虚拟 DOM 等的代码。基本上就是除去编译器的其它一切。
源码入口文件
| 完整版(编译器+运行时) | 编译器 | 运行时 |
|---|---|---|
| entry-runtime-with-compiler.js | entry-compiler.js | entry-runtime.js |
区别
运行时(entry-runtime.js)
Vue.prototype.$mount = function (el?: string | Element,hydrating?: boolean): Component {el = el && inBrowser ? query(el) : undefinedreturn mountComponent(this, el, hydrating)}
完整版(entry-runtime-with-compiler.js)
const idToTemplate = cached(id => {const el = query(id)return el && el.innerHTML})/*** Get outerHTML of elements, taking care* of SVG elements in IE as well.*/function getOuterHTML (el: Element): string {// 从注释来看,svg是没有outerHTML的,// 想要获取html字符串要做兼容if (el.outerHTML) {return el.outerHTML} else {const container = document.createElement('div')container.appendChild(el.cloneNode(true))return container.innerHTML}}const mount = Vue.prototype.$mountVue.prototype.$mount = function (el?: string | Element,hydrating?: boolean): Component {el = el && query(el)/* istanbul ignore if */if (el === document.body || el === document.documentElement) {// el 不能为body和htmlprocess.env.NODE_ENV !== 'production' && warn(`Do not mount Vue to <html> or <body> - mount to normal elements instead.`)return this}const options = this.$options// resolve template/el and convert to render functionif (!options.render) {// 没有render函数,如果 Vue 选项中包含渲染函数,该模板将被忽略。let template = options.templateif (template) {// 使用了模版语法if (typeof template === 'string') {if (template.charAt(0) === '#') {// 如果值以 # 开始,则它将被用作选择符,并使用匹配元素的 innerHTML 作为模板。template = idToTemplate(template)/* istanbul ignore if */if (process.env.NODE_ENV !== 'production' && !template) {warn(`Template element not found or is empty: ${options.template}`,this)}}} else if (template.nodeType) {// 判断这是一段htmltemplate = template.innerHTML} else {if (process.env.NODE_ENV !== 'production') {warn('invalid template option:' + template, this)}return this}} else if (el) {// 使用了el的情况template = getOuterHTML(el)}if (template) {/* istanbul ignore if */if (process.env.NODE_ENV !== 'production' && config.performance && mark) {mark('compile')}const { render, staticRenderFns } = compileToFunctions(template, {outputSourceRange: process.env.NODE_ENV !== 'production',shouldDecodeNewlines,shouldDecodeNewlinesForHref,delimiters: options.delimiters,comments: options.comments}, this)// 用compile方法,将template转换成renderoptions.render = renderoptions.staticRenderFns = staticRenderFns/* istanbul ignore if */if (process.env.NODE_ENV !== 'production' && config.performance && mark) {mark('compile end')measure(`vue ${this._name} compile`, 'compile', 'compile end')}}}return mount.call(this, el, hydrating)}
从源码来看,完整版多了针对template的处理,使用compile方法将template转换成了render函数。
