【IMWeb训练营作业】select

来源:互联网 发布:创业方向 知乎 编辑:程序博客网 时间:2024/05/22 13:38

时间飞逝,在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里面也自定义了一个属性list来接收父组件传过来的list,同样在custom-list里面的props也定义了list

<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"]}});


1 0