在用Vue腳手架快速搭建一個項目時,在初始化時有一個選擇runtime+compiler
還是runtime-only
的選項,那麼這兩個配置有什麼區別呢?
如下圖,當一個Vue程序被運行時,一般它會經歷如下過程。
#1 template加載如vm.options中
#2 解析爲ast(抽象語法樹)
#3 編譯爲一個render()函數
#4 渲染爲虛擬DOM
#5 渲染爲真實DOM(呈現出UI界面)
而runtime+compiler
和runtime-only
的區別,則主要體現在main.js的這一處代碼中:
//runtime+compiler
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
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
render:h => h(APP)
})
由此可見,在執行一個Vue程序時,兩者具有如下區別:
//runtime + compiler
template -> ast -> render -> virtual DOM -> UI
//runtime-only
render -> virtual DOM -> UI
顯然,採用 runtime-only 的項目的性能將更高,並且對於同樣的功能,runtime-only使用更少的代碼就能完成。
h函數
在runtime-only的Vue實例中用到了一個 h函數,它實質上是一個 createElment()函數
,該函數接受三個參數,分別是 標籤(字符串)、標籤屬性(對象)、內容(數組)。
如:
createElement('h2',{'class':'highlighter'},['Hello,Vue!'])
//這將創建一個<h2></h2>標籤,並且替換掉該Vue實例掛載的HTML
除此之外,createElment() 還能接受一個組件對象。當它接受一個組件對象時,它做的事情與在Vue實例中處理組件對象的步驟基本一致。這也是爲什麼runtime-only的Vue項目程序可以直接從render開始執行的緣故。
這裏你可能會有疑惑,在.vue文件中照樣還是存在着<template></template>
代碼啊,那麼這些代碼是怎麼被處理的?爲什麼它們就不需要 template -> ast 這一過程。
實際上,<template></template>
中的代碼在被加載入 main.js 之前就會被編譯爲 render函數,而完成這一工作的,是 vue-template-compiler
loader。該loader可以在package.json中被找到。
所以結論就是:
在開發中,如果你需要在js文件中用template,那麼就用template-compiler,如果你的template都在.vue文件中,那麼用template-only。