时间飞逝,在10天训练营的日子快要结束了。这次带来第二次作业,一个简单的select组件,先来看看效果图:
效果图
功能简析
Vue其中一个核心概念就是组合的组件化,根据效果图,我们可以知道下拉框和弹出的内容统称为一个select组件,其中还可以根据弹出的内容再分为一个组件。首先要注册一个组件,这里可以用局部组件,也可以用全局组件。我注册了一个custom-select组件,在模板中使用<custom-select></custom-select>的形式,相当于扩展了HTML标签。然后这个组件里面还有一个子组件custom-list,用来控制弹出内容。
1.事件监控器v-on用来监控input框的鼠标点击事件,使得下面的弹出内容div显示或者隐藏
2.我们还注意到两个搜索框的按钮不一样,一个叫做“搜索”,一个叫做“查询”,这里涉及到父组件到子组件通信的技术。不难想到,我们只需要改变input框的value值就可以实现,那么这个值怎么传入到那里呢?在父组件自定义一个属性btn-value,并在子组件的选项对象里通过props告知子组件有这么一个值,并且绑定input的value值来接收这个值,这样就实现了两个按钮的不同。可以看到,组件化使得代码的复用性高。
<custom-select btn-value="搜索" ></custom-select>
<custom-select btn-value="查询" ></custom-select>
<input type="button" :value="btnValue">
props:["btnValue"]
3.下面来一个更加深入的父到子的通信。大家注意到子组件的弹出内容不同,假设有这么两个数据list1和list2它们存储在根实例的data选项里,它先要通过custom-select,再到custom-list,
new Vue({
el:"#app",
data:{
list1:["beijing","shanghai","hanzhou"],
list2:["17-2-17","17-2-18","17-2-19"]
}
});
我们通过绑定自定义属性list,分别赋值list1,list2来传递,当然在custom-select组件里的props选项定义了list
<custom-select btn-value="搜索" v-bind:list="list1" ></custom-select>
<custom-select btn-value="查询" v-bind:list="list2" ></custom-select>
<custom-list v-show="selectShow" :list="list" >
从上面的例子可以看出,父到子的通信通过自定义属性来传递。
4.接下来实现选中弹出内容的一条,就把这个内容显示在input框上。这里涉及了子到父的通信。
在子组件上的li上定义一个点击事件,并使它发射一个事件receive,实际上是告知父组件,有这么一个事件。
<li v-for="item of list" @click="selectValue(item)">{{item}}</li>
methods:{
selectValue:function(item){
//点击了一下 在子组件中有交互 告知父级改变val的值
this.$emit("receive",item)
}
}
告知了父组件,父组件需要监听它,并且改变相应的value值
<custom-list
v-show="selectShow"
:list="list"
@receive="changeValue"
>
</custom-list>
methods:{
changeValue(value){
this.val= value;
}
显然我们可以知道 :子到父的通信需要自定义事件
到此,我们就完成了一个简单的select组件功能
核心代码:
Vue.component("custom-list",{
props:["list"],
template:`<ul class="list" >
<li v-for="item of list" @click="selectValue(item)">{{item}}</li>
</ul>`,
methods:{
selectValue:function(item){
//点击了一下 在子组件中有交互 告知父级改变val的值
this.$emit("receive",item)
}
}
})
Vue.component("custom-select",{
data(){
return {
selectShow:false,
val:''
};
},
props:["btnValue","list"],
template: `<section class="warp">
<div class="searchIpt clearfix">
<div class="clearfix">
<input type="text" class="keyWord"
:value="val"
@click="selectShow=!selectShow">
<input type="button" :value="btnValue">
<span></span>
</div>
<custom-list
v-show="selectShow"
:list="list"
@receive="changeValue"
>
</custom-list>
</div>
</section>`,
methods:{
changeValue(value){
this.val= value;
}
}
}
);
new Vue({
el:"#app",
data:{
list1:["beijing","shanghai","hanzhou"],
list2:["17-2-17","17-2-18","17-2-19"]
}
});