Vue組件玲躯,擴(kuò)展html荚虚,封裝可重用的代碼
組件命名方式有兩種
(1)短橫線分隔命名添怔,如 'b-box'
(2)PascalCase首字母大寫(xiě)命名即大駝峰,但是當(dāng)使用 PascalCase 定義組件時(shí)续徽,在html文檔里引用時(shí)必須使用kebab-case短橫線分隔命名才生效畏妖,否則報(bào)錯(cuò)傅瞻,如'TableBox'要寫(xiě)成'table-box'
原因:因?yàn)镠TML對(duì)大小寫(xiě)不敏感踢代,JS對(duì)大小寫(xiě)敏感
組件里的data屬性必須是一個(gè)函數(shù)
1.局部組件
在Vue實(shí)例中,創(chuàng)建一個(gè)components對(duì)象嗅骄,里面定義組件名稱胳挎,一些數(shù)據(jù)方法等,先定義一個(gè)組件名稱溺森,template里寫(xiě)的是可重用的HTML模板慕爬,props里定義的是一些靜態(tài)屬性
components: {
'b-box': {
template: `<div class="box">
<h2 class="title">{{title}}</h2>
<p class="content">{{content}}</p>
</div>`,
props: ['title', 'content']
}
}
當(dāng)要使用這個(gè)模板時(shí),標(biāo)簽就是要使用的組件名屏积,在Vue實(shí)例中澡罚,掛載對(duì)象,定義相關(guān)的數(shù)據(jù)肾请,然后組件就可綁定這些數(shù)據(jù)留搔,渲染頁(yè)面
<div id="app">
<b-box v-for="(item,index) in list" :key="index"
:title="item.title" :content="item.content"></b-box>
</div>
注意:局部組件只能在當(dāng)前Vue實(shí)例作用域下有效
2.全局組件
全局組件必須寫(xiě)在Vue實(shí)例創(chuàng)建之前,才在該根元素下面生效铛铁;
Vue.component:(
'b-count', {
template: `<div class="content" >
<span>{{types}}</span>
<div>
<button @click="MyCount--" :disabled="MyCount===1">-</button>
<input type="text" :value="MyCount">
<button @click="MyCount++" :disabled="MyCount===10">+</button>
</div>
</div>`,
})
組件間的數(shù)據(jù)傳遞
子組件通過(guò)$emit可以觸發(fā)事件隔显,第一個(gè)參數(shù)為要觸發(fā)的事件却妨,第二個(gè)事件為要傳遞的數(shù)據(jù)
在組件中來(lái)監(jiān)聽(tīng)MyCount值的變化
watch: {
MyCount(val) {
console.log(val);
this.$emit('synccount', val)
}
}
在Vue實(shí)例中接收MyCount值的變化
methods: {
synccount(index, e) {
this.list[index].count = e
}
}
在模板中點(diǎn)擊觸發(fā)事件
<b-count v-for="(item,index) in list" :key="index" :types="item.types" :count="item.count"
@synccount="synccount(index,$event)">
</b-count>
3.父子組件
$parent是獲取父組件對(duì)象
$root是獲取根組件對(duì)象
$children是獲取子組件對(duì)象
$ref返回的是一個(gè)對(duì)象,對(duì)象中包含所有帶有ref屬性的組件
父組件
ue.component('b-tabs', {
template:`
<div class="tabs">
<ul class="title">
<li @click="activeIndex=index" :class="{active:activeIndex===index}" v-for="(item,index) in titles" :key="index">{{item}}</li>
</ul>
<ul class="content">
<slot></slot>
</ul>
</div>
`,
data() {
return {
//高亮索引
activeIndex:0,
//定義titles數(shù)組
titles:[]
}
},
watch:{
//監(jiān)聽(tīng)高亮索引
activeIndex(val){
//先隱藏所有的子組件
this.$children.forEach(c=>c.isShow=false)
//再顯示當(dāng)前高度的子組件
this.$children[val].isShow = true
}
},
// 父組件掛載完成時(shí)括眠,所有的子組件一定全部都掛載完成了
mounted() {
this.$children[this.activeIndex].isShow = true
},
})
子組件
Vue.component('b-tabs-item', {
props:['title'],
template:`
<li v-show="isShow">
<slot></slot>
</li>
`,
data() {
return {
//是否顯示
isShow:false
}
},
created() {
// 在子組件的created生命周期函數(shù)中彪标,可以獲取到父組件的數(shù)據(jù)
this.$parent.titles.push(this.title)
},
})
模板運(yùn)用
<div id="app">
<b-tabs>
<b-tabs-item title="南京">
<li>南京的鹽水鴨真好吃</li>
</b-tabs-item>
<b-tabs-item title="北京">
<ul>
<li>北京的烤鴨真好吃</li>
</ul>
</b-tabs-item>
<b-tabs-item title="無(wú)錫">
<a href="#">無(wú)錫的小籠包真好吃</a>
</b-tabs-item>
</b-tabs>
</div>
運(yùn)行截圖
插槽問(wèn)題
用<slot></slot>來(lái)表示,相當(dāng)于一個(gè)占位符掷豺,父組件可以在這個(gè)占位符中填充任何模板代碼捞烟,如 HTML、組件等当船,填充內(nèi)容會(huì)替換子組件的<slot></slot>標(biāo)簽题画。如果子組件沒(méi)有使用插槽,父組件如果需要往子組件中填充模板或者h(yuǎn)tml, 是沒(méi)法做到的德频。
4.第三方組件庫(kù)
如element-ui,vant,iview等苍息,在需要使用的頁(yè)面中引入其樣式及文件,就可以使用了壹置,簡(jiǎn)單又高效