【IMWeb训练营作业】select

时间飞逝,在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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值