1. Vue組件名推薦使用駝峰命名
現(xiàn)在我們來(lái)看看為什么在Vue中推薦注冊(cè)組件是使用駝峰寫法, 在了解這個(gè)之前,詳細(xì)大家應(yīng)該都能明白為什么在Vue中, 局部組件的使用頻率高于全局組件.
推薦使用駝峰寫法也是和局部組件有關(guān)系
我們先看一個(gè)示例
<div id="app">
<!-- 3. 在注冊(cè)了局部組件的實(shí)例中使用局部組件 -->
<my-component></my-component>
</div>
<script>
// 1. 創(chuàng)建局部組件的選項(xiàng)對(duì)象
let MyComponent = {
template: `
<div>
<h2>局部組件</h2>
</div>
`,
}
const vm = new Vue({
el:"#app",
// 2. 將選項(xiàng)對(duì)象注冊(cè)為局部組件
components: {
"my-component": MyComponent
}
})
</script>
通過前面的學(xué)習(xí),這個(gè)例子應(yīng)該已經(jīng)熟悉了,
- 首先定義一個(gè)選項(xiàng)對(duì)象
myComponent
- 在Vue實(shí)例中通過
components
注冊(cè)為局部組件 - 在HTML模板中通過
<my-component>
自定義標(biāo)簽使用組件
示例中,不使用駝峰命名組件,依然可以正常運(yùn)行,那么為什么組件名還要推薦使用駝峰命名
那先看下面幾點(diǎn):
- 首先在定義選項(xiàng)對(duì)象的時(shí)候使用的變量名絕對(duì)不可以是連字符, 這是標(biāo)識(shí)符命名規(guī)范,因此如果要使用連字符就必須加引號(hào)
- 在注冊(cè)組件是,
components
中的屬性名my-component
就是我們的組件名稱, 其值MyComponent
就是將誰(shuí)注冊(cè)為組件
好此時(shí)大家想一想,如果組件名和選項(xiàng)對(duì)象的變量名一樣會(huì)怎么樣
是不是就會(huì)變成如下的寫法
const vm = new Vue({
el:"#app",
components: {
MyComponent: MyComponent
}
})
在思考一下,我們之前在學(xué)習(xí)ES6的時(shí)候講過在定義對(duì)象的是有一種簡(jiǎn)便寫法. 當(dāng)屬性跟值長(zhǎng)得一樣時(shí),就可以簡(jiǎn)寫
因此這里我們就可以簡(jiǎn)寫為
const vm = new Vue({
el:"#app",
components: {
MyComponent
}
})
所以,為什么推薦使用駝峰寫法,這里就應(yīng)該可以看出端倪了, 如果我們定義組件的組件名使用駝峰寫法,也就是和需要被注冊(cè)為組件的選項(xiàng)對(duì)象一致是,我們注冊(cè)組件將變得簡(jiǎn)單
如果此時(shí)需要注冊(cè)n個(gè)組件,就可以如下寫法
const vm = new Vue({
el:"#app",
components: {
one,two,three,four.....
}
})
是不是感覺很優(yōu)雅,
總結(jié):
- 在定義組件時(shí)推薦使用駝峰寫法,最好的組件名和需要被創(chuàng)建為組件的選項(xiàng)對(duì)象名一致
- 使用組件時(shí)推薦使用連字符
2. 組件中的template 選項(xiàng)
盡管語(yǔ)法糖簡(jiǎn)化了組件注冊(cè),但在template選項(xiàng)中拼接HTML元素比較麻煩,這也導(dǎo)致了HTML和JavaScript的高耦合性肩豁。
Vue.js提供了兩種方式將定義在JavaScript中的HTML模板分離出來(lái)缀程。
2.1 使用script標(biāo)簽將template模板分離出來(lái)
在使用script標(biāo)簽將template模板分離出來(lái)時(shí),要注意script標(biāo)簽的type類型選擇,
<div id="app">
<!-- 3. 使用組件 -->
<my-component></my-component>
</div>
<!-- 組件模板 -->
<!-- 注意: 如果不添加type屬性,可能會(huì)顯示效果,但是會(huì)報(bào)錯(cuò), -->
<script id="myComponent" type="text/x-template">
<div>
<h2>我想被創(chuàng)建為局部組件</h2>
</div>
</script>
<script>
// 1. 創(chuàng)建組件選項(xiàng)對(duì)象
let MyComponent = {
// 此時(shí)的模板template的值就是一個(gè)選擇器
template: "#myComponent",
}
const vm = new Vue({
el:"#app",
// 2. 注冊(cè)組件
components: {
"my-component": MyComponent
}
})
</script>
template選項(xiàng)現(xiàn)在不再是HTML元素涧至,而是一個(gè)id艇拍,Vue.js根據(jù)這個(gè)id查找對(duì)應(yīng)的元素锅减,然后將這個(gè)元素內(nèi)的HTML作為模板進(jìn)行編譯辐董。
注意:
使用
<script>
標(biāo)簽時(shí),type指定為text/x-template
白对,意在告訴瀏覽器這不是一段js腳本掠廓,瀏覽器在解析HTML文檔時(shí)會(huì)忽略<script>
標(biāo)簽內(nèi)定義的內(nèi)容。
2.2 使用template 標(biāo)簽處理模板
如果使用<template>
標(biāo)簽甩恼,則不需要指定type屬性蟀瞧。
<div id="app">
<!-- 3. 使用組件 -->
<my-component></my-component>
</div>
<!-- 組件模板 -->
<!-- template標(biāo)簽不需要指定type,標(biāo)簽的本意就是告訴瀏覽器這是模板 -->
<template id="myComponent">
<div>
<h2>我想被創(chuàng)建為局部組件</h2>
</div>
</template>
<script>
// 1. 創(chuàng)建組件選項(xiàng)對(duì)象
let MyComponent = {
// 此時(shí)的模板template的值就是一個(gè)選擇器
template: "#myComponent",
}
const vm = new Vue({
el:"#app",
// 2. 注冊(cè)組件
components: {
"my-component": MyComponent
}
})
</script>
在理解了組件的創(chuàng)建和注冊(cè)過程后沉颂,我建議使用<script>
或<template>
標(biāo)簽來(lái)定義組件的HTML模板。
這使得HTML代碼和JavaScript代碼是分離的黄橘,便于閱讀和維護(hù)兆览。
另外,在Vue.js中塞关,可創(chuàng)建.vue
后綴的文件抬探,.vue
文件就是一個(gè)組件,成為單文件組件,這個(gè)內(nèi)容我會(huì)在后面的文章介紹帆赢。
3. 組件選項(xiàng)對(duì)象中的特例
組件中的選項(xiàng)基本與實(shí)例選項(xiàng)對(duì)象一致, 但是有兩個(gè)選項(xiàng)是特例,分別為el 和 data 屬性
這個(gè)說(shuō)的特例是指組件的選項(xiàng)對(duì)象和實(shí)例選項(xiàng)對(duì)象使用的不同
3.1 在組件中不能使用el
el
屬性的作用我們都了解了, 就是在實(shí)例中使用,決定Vue需要接管的DOM元素. 組件是在實(shí)例中使用,所以不需要el屬性,
如果一個(gè)選項(xiàng)對(duì)象被注冊(cè)為組件,添加el
屬性就會(huì)造成報(bào)錯(cuò),
// 1. 創(chuàng)建局部組件的選項(xiàng)對(duì)象
let MyComponent = {
el:"",
template: "#myComponent",
}
const vm = new Vue({
el:"#app",
// 2. 將選項(xiàng)對(duì)象注冊(cè)為局部組件
components: {
"my-component": MyComponent
}
})
// 會(huì)報(bào)錯(cuò), 告訴你el屬性只能在實(shí)例中使用
可以通過報(bào)錯(cuò)信息了解到, el
選項(xiàng)只能使用在new
創(chuàng)建的vue實(shí)例上
3.2 組件中data屬性值必須是一個(gè)函數(shù),
組件中的data
選項(xiàng)必須是一個(gè)函數(shù),返回一個(gè)數(shù)據(jù)對(duì)象.
為什么需要是一個(gè)函數(shù),而不可以像Vue實(shí)例的選項(xiàng)對(duì)象一樣是一個(gè)對(duì)象呢
3.2.1 組件data屬性值如果是一個(gè)對(duì)象的問題
不能使用對(duì)象的原因:
- 首先因?yàn)榻M件會(huì)被多次復(fù)用,
- 而對(duì)象是引用數(shù)據(jù)類型,如果組件數(shù)據(jù)使用對(duì)象的話,那么組件所有的復(fù)用都共享這些數(shù)據(jù),
這樣就會(huì)出現(xiàn)問題,看代碼:
示例代碼如下:
<div id="app">
<!-- 3. 使用組件 -->
<my-component></my-component>
<my-component></my-component>
<my-component></my-component>
</div>
<template id="myComponent">
<div>
<h2>組件{{num}}</h2>
<button @click="handleClick">點(diǎn)擊+1</button>
</div>
</template>
<script>
// 組件共享數(shù)據(jù)
let data = {
num : 10
}
// 1. 選項(xiàng)對(duì)象
let MyComponent = {
template: "#myComponent",
data: function(){
return data
},
methods: {
handleClick(){
this.num++
}
}
}
const vm = new Vue({
el:"#app",
// 2. 注冊(cè)組件
components: {
"my-component": MyComponent
}
})
</script>
示例結(jié)果:
實(shí)例說(shuō)明:
- 如果在組件的
data
中直接寫對(duì)象就會(huì)報(bào)錯(cuò), - 因此我們將
data
函數(shù)中返回的對(duì)象提取出來(lái).這樣所有的組件都共用一個(gè)數(shù)據(jù)對(duì)象. - 一次來(lái)模擬組件
data
選項(xiàng)值為對(duì)象的情景
通過案例我們就會(huì)發(fā)現(xiàn)如果所有的組件都共享數(shù)據(jù),當(dāng)有一個(gè)組件中的數(shù)據(jù)發(fā)生了變化,所有的組件顯示的數(shù)據(jù)都會(huì)發(fā)生變化, 這不是我們想要的,
3.2.2 解決組件共享數(shù)據(jù)的問題
所以組件的data數(shù)據(jù)屬性才會(huì)需要函數(shù),每次初始化化的時(shí)候都會(huì)執(zhí)行函數(shù),將返回的結(jié)果作為組件的數(shù)據(jù),
這樣每次執(zhí)行函數(shù)都會(huì)給每個(gè)組件創(chuàng)建一個(gè)獨(dú)立的數(shù)據(jù)
<div id="app">
<!-- 3. 使用組件 -->
<my-component></my-component>
<my-component></my-component>
<my-component></my-component>
</div>
<template id="myComponent">
<div>
<h2>組件{{num}}</h2>
<button @click="handleClick">點(diǎn)擊+1</button>
</div>
</template>
<script>
// 1. 選項(xiàng)對(duì)象
let MyComponent = {
template: "#myComponent",
data: function(){
// 每次函數(shù)執(zhí)行都會(huì)返回新的數(shù)據(jù),非共享數(shù)據(jù)
return {
num : 10
}
},
methods: {
handleClick(){
this.num++
}
}
}
const vm = new Vue({
el:"#app",
// 2. 注冊(cè)組件
components: {
"my-component": MyComponent
}
})
</script>
顯示結(jié)果:
通過示例就會(huì)發(fā)現(xiàn), 當(dāng)一個(gè)組件數(shù)據(jù)發(fā)生改變的時(shí)候, 其他組件的數(shù)據(jù)不會(huì)變化,因?yàn)槊總€(gè)組件都有自己獨(dú)立的數(shù)據(jù)
3.3 組件的命名
當(dāng)注冊(cè)組件 (或者 prop) 時(shí)小压,可以使用 kebab-case (短橫線分隔命名)、camelCase (駝峰式命名) 或 PascalCase (單詞首字母大寫命名)椰于。
// 在組件定義中
components: {
// 使用 kebab-case 注冊(cè)
'kebab-cased-component': { /* ... */ },
// 使用 camelCase 注冊(cè) 俗稱小駝峰
'camelCasedComponent': { /* ... */ },
// 使用 PascalCase 注冊(cè) 俗稱大駝峰
'PascalCasedComponent': { /* ... */ }
}
在 HTML 模板中怠益,請(qǐng)使用 kebab-case:
<!-- 在 HTML 模板中始終使用 kebab-case -->
<kebab-cased-component></kebab-cased-component>
<camel-cased-component></camel-cased-component>
<pascal-cased-component></pascal-cased-component>
這個(gè)問題已經(jīng)在前面認(rèn)真探討過了,這里不再詳細(xì)闡述
4. 組件使用問題
通過上面上的例子我們已經(jīng)了解了組件的使用,就是把組件名當(dāng)做自定義標(biāo)簽使用,但是這種使用方法有的時(shí)候也會(huì)出現(xiàn)問題,
4.1. 組件標(biāo)簽解析錯(cuò)誤
通過下面的實(shí)例了解組件標(biāo)簽解析是發(fā)生的問題.
例如:實(shí)例代碼如下
<div id="app">
<!-- 3. 使用組件 -->
<table>
<tbody>
<row></row>
<row></row>
<row></row>
</tbody>
</table>
</div>
<!-- 組件模板 -->
<template id="myComponent">
<tr>
<td>內(nèi)容</td>
<td>123</td>
</tr>
</template>
<script>
// 1. 組件選項(xiàng)對(duì)象
let MyComponent = {
template: "#myComponent",
}
// 2. 注冊(cè)組件
const vm = new Vue({
el:"#app",
components: {
"row": MyComponent
}
})
</script>
顯示結(jié)果:
實(shí)例中的寫法,在查看代碼結(jié)構(gòu)時(shí),發(fā)現(xiàn)子組件的tr標(biāo)簽并不在tbody里,
原因在與瀏覽器規(guī)范中tbody
標(biāo)簽里面必須放tr
標(biāo)簽,但是我們放的是row
自定義標(biāo)簽,所以在解析的時(shí)候就會(huì)出問題
諸如此類的還有ul
,ol
標(biāo)簽里只能放li
標(biāo)簽, select
標(biāo)簽中只能放option
,這些都是需要注意的事項(xiàng)
那么我們?cè)趺唇鉀Q這類問題呢?
4.2 通過is屬性使用組件
vue允許我們使用is
屬性來(lái)使用組件, is
屬性的值是組件名
所以可以采用is
屬性來(lái)制定組件
示例代碼如下:
<div id="app">
<!-- 3. 使用組件 -->
<table>
<tbody>
<tr is="row"></tr>
<tr is="row"/>
<tr is="row"/>
</tbody>
</table>
</div>
顯示結(jié)果:
此時(shí)我們就會(huì)發(fā)現(xiàn)不僅結(jié)果沒問題, 編譯后標(biāo)簽的嵌套也沒有什么問題,
因?yàn)槲覀兪前凑諛?biāo)準(zhǔn)在tbody
標(biāo)簽中使用的是tr
標(biāo)簽,只不過通過is
屬性將tr
標(biāo)簽替換為了組件row
的模板標(biāo)簽.
此時(shí)tr
標(biāo)簽中沒有嵌套內(nèi)容,所有使用單標(biāo)簽,雙標(biāo)簽都可以