vue 至少有7種定義組件模板的方法:
- 字符串
- 模板字面量
- X-Templates
- 內(nèi)聯(lián)模板
- 渲染方法(Render)
- JSX
- 單文件組件
字符串
默認是在js文件中定義成字符串的形式. 我想我們都會同意在字符串中定義模板是很難以理解的.除了為了更廣泛的瀏覽器支持, 這種方法沒多大用處.
Vue.component('my-checkbox', {
template: `<div class="checkbox-wrapper" @click="check"><div :class="{ checkbox: true, checked: checked }">{{title}}</div><div class="title"></div></div>`,
data() {
return { checked: false, title: 'Check me' }
},
methods: {
check() { this.checked = !this.checked; }
}
});
模板字面量
es6的模板字面量("反引號")允許你使用在一般的javascript字符串中無法做到的多行定義你的模板. 這種方式更易讀, 而且在很多新的瀏覽器中都得到了支持, 但是為了安全, 你仍然應該編譯為es5.
不過, 這種方法也并不是完美的; 我發(fā)現(xiàn)大多數(shù) IDE 仍然會通過語法高亮, 以及格式化tab和換行等問題使你痛苦.
Vue.component('my-checkbox', {
template: `<div class="checkbox-wrapper" @click="check">
<div :class="{ checkbox: true, checked: checked }"></div>
<div class="title"></div>
</div>`,
data() {
return { checked: false, title: 'Check me' }
},
methods: {
check() { this.checked = !this.checked; }
}
});
X-Templates
通過這種方法, 你的模板被定義在index.html的一個script標簽內(nèi). script標簽被標記為text/x-template并且在你的組件定義中通過id來引用.
我喜歡這個方法允許你在適當?shù)膆tml標記中編寫你的html, 但它的缺點是, 它把模板和組件定義的其他部分分離開了.
Vue.component('my-checkbox', {
template: '#checkbox-template',
data() {
return { checked: false, title: 'Check me' }
},
methods: {
check() { this.checked = !this.checked; }
}
});
<script type="text/x-template" id="checkbox-template">
<div class="checkbox-wrapper" @click="check">
<div :class="{ checkbox: true, checked: checked }"></div>
<div class="title"></div>
</div>
</script>
內(nèi)聯(lián)模板
通過給組件添加inline-template屬性, 你向vue表明, 組件的內(nèi)容是它的模板, 而不
是把它作為分布式內(nèi)容(參考 插槽slot)
這和x-template面臨一樣的問題, 但是優(yōu)點是html模板內(nèi)容是在正確的地方, 所以可以在頁面加載時渲染而不是等待js執(zhí)行.
Vue.component('my-checkbox', {
data() {
return { checked: false, title: 'Check me' }
},
methods: {
check() { this.checked = !this.checked; }
}
});
<my-checkbox inline-template>
<div class="checkbox-wrapper" @click="check">
<div :class="{ checkbox: true, checked: checked }"></div>
<div class="title"></div>
</div>
</my-checkbox>
渲染方法(Render)
Render方法需要你把你的模板定義為javascript對象. 這顯然是最詳細和最抽象的模板選擇.
但是, 優(yōu)點是模板更接近編譯器, 以及給你完整的訪問javascript功能的權限, 而不是指令提供的子集.
Vue.component('my-checkbox', {
data() {
return { checked: false, title: 'Check me' }
},
methods: {
check() { this.checked = !this.checked; }
},
render(createElement) {
return createElement(
'div',
{
attrs: {
'class': 'checkbox-wrapper'
},
on: {
click: this.check
}
},
[
createElement(
'div',
{
'class': {
checkbox: true,
checked: this.checked
}
}
),
createElement(
'div',
{
attrs: {
'class': 'title'
}
},
[ this.title ]
)
]
);
}
});
JSX
Vue最具爭議的模板選項是JSX. 一些開發(fā)者認為JSX是丑陋, 不直觀, 而且是對Vue精神的背叛.
因為JSX對瀏覽器不可讀, 所以首先需要你編譯. 但是, 如果你需要使用渲染(Render)函數(shù), JSX是一種不那么抽象的定義模板的方式.
Vue.component('my-checkbox', {
data() {
return { checked: false, title: 'Check me' }
},
methods: {
check() { this.checked = !this.checked; }
},
render() {
return <div class="checkbox-wrapper" onClick={ this.check }>
<div class={{ checkbox: true, checked: this.checked }}></div>
<div class="title">{ this.title }</div>
</div>
}
});
單文件組件
只要你熟悉構建工具的設置, 單文件組件絕對是模板選擇的王者.
他們帶來兩全其美的方法: 允許你編寫html標記, 同時保持所有的組件定義在一個文件中.
盡管需要編譯以及一些IDE不支持這種文件類型(.vue)的語法高亮外, 但仍然無法撼動其地位.
<template>
<div class="checkbox-wrapper" @click="check">
<div :class="{ checkbox: true, checked: checked }"></div>
<div class="title"></div>
</div>
</template>
<script>
export default {
data() {
return { checked: false, title: 'Check me' }
},
methods: {
check() { this.checked = !this.checked; }
}
}
</script>
在使用了像帶SFCS的Pug之類的模板預處理器之后, 你可能會說, 還有更多定義模板的方式.
哪一個是最好的?
當然都不是最完美的方式, 需要看你的具體使用情況了. 我認為最好的開發(fā)人員會注意到所有的可能性,并將它們作當做vue的工具來使用.
翻譯自: https://vuejsdevelopers.com/2017/03/24/vue-js-component-templates
補充
IE11不支持 data(){} 這種形式的定義, 改為如下方式即可:
data: function () {
return { checked: false, title: 'Check me' }
}