runtime-compiler和runtime-only区别
runtime-compiler里的main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
components: { App },
template: '<App/>'
})
runtime-only里的mian.js
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
render: h => h(App)
})
当我们将template模板传给vue时,会在vue实例下的options里保存
然后将template解析(parse)成抽象语法树(abstract syntax tree)
然后将抽象语法树编译(compiler)成render函数。
最终将template翻译成虚拟DOM(virtual),然后选染成真实DOM。显示在UI上。
runtime-only:render函数->虚拟dom->ui
runtime-compiler:template->ast->render->vdom->ui
上边代码少了前两个步骤,直接给你render函数,代码量更少,性能更高。
render函数用法一
new Vue({
el: '#app',
//components: { App },
//template: '<App/>'
render: function (createElement) {
//参数:creatElement(‘标签’,{标签的属性},['标签里的内容'])
return createElement('h2',{class:'box'},['hello world'])
}
})
使用render函数就会代替原来的template,直接替换#app这个div.
createElement函数有三个参数,分别是标签名,标签属性为对象,标签内容数组,可以省略后两个参数
标签内容中可以再嵌套标签
参数里可以继续嵌套这个函数createElement,实现标签嵌套标签。
render: function (createElement) {
//参数:creatElement(‘标签’,{标签的属性},['标签里的内容'])
return createElement('h2',
{class: 'box'},
['hello world',
createElement('button'),['按钮']])
}
render函数用法二:传入组件对象
const Cpn = {
template:'<div>{{message}}</div>',
data() {
return {
message:'我是组件message'
}
}
}
/* eslint-disable no-new */
new Vue({
el: '#app',
//components: { App },
//template: '<App/>'
render: function (createElement) {
//参数:creatElement(‘标签’,{标签的属性},['标签里的内容'])
/* return createElement('h2',
{class: 'box'},
['hello world',
createElement('button',['按钮'])])*/
//用法二:传入组件对象
return createElement(Cpn)
}
})
既然这个函数可以直接传入一个组件,那么每个vue文件,不都是一个组件吗,直接传入App.vue
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
//components: { App },
//template: '<App/>'
render: function (createElement) {
//参数:creatElement(‘标签’,{标签的属性},['标签里的内容'])
/* return createElement('h2',
{class: 'box'},
['hello world',
createElement('button',['按钮'])])*/
//用法二:传入组件对象
return createElement(App)
}
})
在runtime-only里边不还是有template模板吗
<template>
<div id="app">
<img src="./assets/logo.png">
<HelloWorld/>
</div>
</template>
那么他是否会像runtime-compilier一样将模板保存在vue实例里,再解析到抽象语法树,再辨析成render函数呢
我们试试App.vue里有没有template
import Vue from 'vue'
import App from './App'
console.log(App)
看到对象里的render函数了吗,已经将template编译成render函数了,那么vue文件里的template是由谁处理的呢
是由vue-template-compiler来解析的,之前我们配置webpack时,安装了开发时依赖vue-template-compiler
综上所述
compiler版本多了mainjs里将template解析成抽象语法树,再将抽象语法树编译成render函数的步骤,
每个vue文件里的template开发时已经被解析成render函数,所以多的这些步骤就是main.js里的这些步骤
el: '#app', components: { App }, template: '<App/>'
我们其实可以直接使用render函数接受App.vue传过来的对象,不用注册,不用template来替换el里挂载的div,会节省这几个步骤,体积更小,效率更高。