自定义组件:
在开发中,为了代码的重用,我们常常会把一个公用的部分,抽象成一个组件;这样,这个组件就可以再多个地方重复使用
- 理解: 用来实现局部(特定)功能效果的代码集合(html/css/js/image…..)
- 为什么: 一个界面的功能很复杂
- 作用: 复用编码, 简化项目编码, 提高运行效率
Vue中使用组件的三大步骤:
一、定义组件(创建组件)
二、注册组件
三、使用组件(写组件标签)
一、如何定义一个组件?
使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;
区别如下:
1.el不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
2.data必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
备注:使用template可以配置组件结构。
二、如何注册组件?
1.局部注册:靠new Vue的时候传入components选项
2.全局注册:靠Vue.component('组件名',组件)
三、编写组件标签:
<b-box></b-box>
自定义内部组件:
<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>
<!-- 准备好一个容器-->
<div id="app">
<!-- 第三步:编写组件标签 -->
<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实例挂载的容器
el: '#app',
components: {
'b-box': {
//组件的模板
template: `
<div>
//使用template选项,定义组件的模板,注意:模板中必须包含一个根标签
<div class='list' v-for="(item,index) in list">
<h2 >{{item.title}}</h2>
<p >{{item.content}}</p>
</div>
</div>
`,
//定义组件的属性,注意:必须要用''
props: ['list']
}
},
// 注意:Vue实例的data选项可以是一个对象,也可以是一个方法,由该方法返回一个对象
// 但是在组件中,data选项必须是一个方法,由该方法返回一个对象
// 因为组件可能会使用很多次,如果data选项是对象的话,会导致多个组件使用了同一份数据。
data() {
return {
list: [{
title: '奔驰',
content: '梅赛德斯-奔驰(Mercedes-Benz)是世界闻名的豪华汽车品 牌。1886年1月,卡尔·本茨发明了世界上第一辆三轮汽车,获得专利(专利号:DRP 37435 [1] ),被誉为“汽车的发明者”。'
},
{
title: '宝马',
content: '宝马(BMW),中文全称为巴伐利亚发动机制造厂股份有限公司,德国汽车品牌,宝马的车系有i、X、Z、纯数字4个车型,1、2、3、4、5、6、7、8等几个系列,还有在各系基础上进行改进的M系(宝马官方的高性能改装部门',
},
{
title: '奥迪',
content: '德国豪华汽车品牌,其标志为四个圆环相扣。现为德国大众汽车公司的子公司。2018年12月20日,2018世界品牌500强排行榜发布,奥迪位列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选项,用于定义组件的属性,有两种方式:1.定义数组,2.定义对象
//注意:props是只读的,不能修改所以需要在data里重新定义一个值用来接收
//用于父组件给子组件传递数据
// 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插槽
插槽的主要作用是帮助我们更好的在其他组件中进行布局。当想要便携可重用的控件时尤为重要。
适用场景:
在自定义编写组件时,多个组件里面的内容不完全相同时,如果疯狂使用v-show或者v-if来控制不同的组件展示不同的内容会有些许的麻烦,插槽就相当于是在父组件页面中的子组件标签里面编写一段代码,然后这段代码会被插入到子组件里面,但是子组件本身是有dom元素的,所以插入的时候需要根据slot标签的位置来决定插入的位置,又或者是根据slot的名称来确定。
<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>全国著名小吃</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:'长沙',
content:'长沙的臭豆腐真好吃'
}
]
}
})
</script>