自定義組件:
在開(kāi)發(fā)中,為了代碼的重用,我們常常會(huì)把一個(gè)公用的部分,抽象成一個(gè)組件;這樣,這個(gè)組件就可以再多個(gè)地方重復(fù)使用
- 理解: 用來(lái)實(shí)現(xiàn)局部(特定)功能效果的代碼集合(html/css/js/image…..)
- 為什么: 一個(gè)界面的功能很復(fù)雜
- 作用: 復(fù)用編碼, 簡(jiǎn)化項(xiàng)目編碼, 提高運(yùn)行效率
Vue中使用組件的三大步驟:
一、定義組件(創(chuàng)建組件)
二、注冊(cè)組件
三、使用組件(寫(xiě)組件標(biāo)簽)
一、如何定義一個(gè)組件?
使用Vue.extend(options)創(chuàng)建,其中options和new Vue(options)時(shí)傳入的那個(gè)options幾乎一樣,但也有點(diǎn)區(qū)別;
區(qū)別如下:
1.el不要寫(xiě),為什么? ——— 最終所有的組件都要經(jīng)過(guò)一個(gè)vm的管理,由vm中的el決定服務(wù)哪個(gè)容器。
2.data必須寫(xiě)成函數(shù),為什么? ———— 避免組件被復(fù)用時(shí),數(shù)據(jù)存在引用關(guān)系。
備注:使用template可以配置組件結(jié)構(gòu)。
二、如何注冊(cè)組件?
1.局部注冊(cè):靠new Vue的時(shí)候傳入components選項(xiàng)
2.全局注冊(cè):靠Vue.component('組件名',組件)
三、編寫(xiě)組件標(biāo)簽:
<b-box></b-box>
自定義內(nèi)部組件:
<style>
*{
margin: 0;
padding: 0;
}
.box{
width: 300px;
border: 1px solid #ccc;
padding: 5px;
margin: 5px;
color: #333;
float: left;
}
.box h2{
font-size: 20px;
text-align: center;
}
.box .content{
font-size: 14px;
border-top: 1px solid #eee;
margin-top: 5px;
padding-top: 5px;
}
</style>
<!-- 準(zhǔn)備好一個(gè)容器-->
<div id="app">
<!-- 第三步:編寫(xiě)組件標(biāo)簽 -->
<b-box v-for="(item,index) in list" :key="index" :title="item.title" :content="item.content"></b-box>
</div>
<script>
let vm = new Vue({
//指定Vue實(shí)例掛載的容器
el: '#app',
components: {
'b-box': {
//組件的模板
template: `
<div>
//使用template選項(xiàng),定義組件的模板,注意:模板中必須包含一個(gè)根標(biāo)簽
<div class='list' v-for="(item,index) in list">
<h2 >{{item.title}}</h2>
<p >{{item.content}}</p>
</div>
</div>
`,
//定義組件的屬性,注意:必須要用''
props: ['list']
}
},
// 注意:Vue實(shí)例的data選項(xiàng)可以是一個(gè)對(duì)象,也可以是一個(gè)方法,由該方法返回一個(gè)對(duì)象
// 但是在組件中,data選項(xiàng)必須是一個(gè)方法,由該方法返回一個(gè)對(duì)象
// 因?yàn)榻M件可能會(huì)使用很多次,如果data選項(xiàng)是對(duì)象的話,會(huì)導(dǎo)致多個(gè)組件使用了同一份數(shù)據(jù)。
data() {
return {
list: [{
title: '奔馳',
content: '梅賽德斯-奔馳(Mercedes-Benz)是世界聞名的豪華汽車(chē)品 牌。1886年1月,卡爾·本茨發(fā)明了世界上第一輛三輪汽車(chē),獲得專利(專利號(hào):DRP 37435 [1] ),被譽(yù)為“汽車(chē)的發(fā)明者”。'
},
{
title: '寶馬',
content: '寶馬(BMW),中文全稱為巴伐利亞發(fā)動(dòng)機(jī)制造廠股份有限公司,德國(guó)汽車(chē)品牌,寶馬的車(chē)系有i、X、Z、純數(shù)字4個(gè)車(chē)型,1、2、3、4、5、6、7、8等幾個(gè)系列,還有在各系基礎(chǔ)上進(jìn)行改進(jìn)的M系(寶馬官方的高性能改裝部門(mén)',
},
{
title: '奧迪',
content: '德國(guó)豪華汽車(chē)品牌,其標(biāo)志為四個(gè)圓環(huán)相扣?,F(xiàn)為德國(guó)大眾汽車(chē)公司的子公司。2018年12月20日,2018世界品牌500強(qiáng)排行榜發(fā)布,奧迪位列51位。'
}
]
};
}
})
</script>
自定義全局組件
<div id='app'>
<b-goods :name='name' :count='count'></b-goods>
</div>
<script>
Vue.component('b-goods', {
template: `
<div class=box>
{{name}}:
<button @click='mycount--' :disabled='mycount===1'>-</button>
<input type="text" v-model='mycount'>
<button @click='mycount++'>+</button>
</div>`,
//props選項(xiàng),用于定義組件的屬性,有兩種方式:1.定義數(shù)組,2.定義對(duì)象
//注意:props是只讀的,不能修改所以需要在data里重新定義一個(gè)值用來(lái)接收
//用于父組件給子組件傳遞數(shù)據(jù)
// props: ['name','count'],
props:{
name:{
type:String
},
count:{
type:Number,
default:1
}
},
data() {
return {
mycount:this.count
}
}
})
Vue.config.productionTip = false
let vm = new Vue({
el: '#app',
components: {},
data() {
return {
name:'衣服',
count:1
};
}
})
</script>
slot插槽
插槽的主要作用是幫助我們更好的在其他組件中進(jìn)行布局。當(dāng)想要便攜可重用的控件時(shí)尤為重要。
適用場(chǎng)景:
在自定義編寫(xiě)組件時(shí),多個(gè)組件里面的內(nèi)容不完全相同時(shí),如果瘋狂使用v-show或者v-if來(lái)控制不同的組件展示不同的內(nèi)容會(huì)有些許的麻煩,插槽就相當(dāng)于是在父組件頁(yè)面中的子組件標(biāo)簽里面編寫(xiě)一段代碼,然后這段代碼會(huì)被插入到子組件里面,但是子組件本身是有dom元素的,所以插入的時(shí)候需要根據(jù)slot標(biāo)簽的位置來(lái)決定插入的位置,又或者是根據(jù)slot的名稱來(lái)確定。
<style>
*{
margin: 0;
padding: 0;
list-style: none;
}
.tab{
width: 400px;
border: 1px solid #ccc;
padding: 5px;
margin: 10px;
overflow: hidden;
}
.tab .titles{
display: flex;
}
.tab .titles li{
border: 1px solid #ccc;
padding: 2px 10px;
margin: 0 2px;
cursor: pointer;
}
.tab .titles li.active{
background-color: orangered;
color:white;
}
.tab .contents{
padding: 5px;
border: 1px solid #ccc;
margin: 4px 2px;
}
</style>
<div id="app">
<b-tab :list="list" :active="activeIndex">
<H2>全國(guó)著名小吃</H2>
</b-tab>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js"></script>
<script>
Vue.config.productionTip = false
// 組件組件
Vue.component('b-tab', {
template:`
<div class="tab">
<slot></slot>
<ul class="titles">
<li @click="activeIndex=index" :class="{active:activeIndex===index}" v-for="(item,index) in list" :key="index">{{item.title}}</li>
</ul>
<ul class="contents">
<li v-show="activeIndex===index" v-for="(item,index) in list" :key="index">{{item.content}}</li>
</ul>
</div>
`,
props:['list','active'],
data() {
return {
activeIndex:this.active
}
},
})
new Vue({
el:'#app',
data:{
//高亮索引
activeIndex:0,
list:[
{
title:'北京',
content:'北京的糖葫蘆真好吃'
},
{
title:'南京',
content:'南京的鹽水鴨真好吃'
},
{
title:'武漢',
content:'武漢的熱干面真好吃'
},
{
title:'長(zhǎng)沙',
content:'長(zhǎng)沙的臭豆腐真好吃'
}
]
}
})
</script>