这是第二次作业,完成select组件
ps:最近这几天在忙着参加创业比赛和广东省大学生职业规划大赛,没时间把做完,终于今天下午可以苟延馋喘下,赶紧把作业补上,毕竟坚持到今天已经是第九天。
学习什么都一样,只要坚持下去总有收获。不说那么多了,直接上效果图
效果
Vue组件
什么是组件?
组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。
知识点
(1)全局注册:要注册一个全局组件,你可以使用 Vue.component(tagName, options)
Vue.component("custom-select",{
data:function(){
},
props:["btn","list"],
template:`<section class="warp">
</section>`,
methods:{
}
}
})
(a) data 必须是一个函数,防止影响到所有组件。
(b)props:props是专门用来暴露组件的属性接口;组件实例的作用域是孤立的。这意味着不能(也不应该)在子组件的模板内直接引用父组件的数据。要让子组件使用父组件的数据,我们需要通过子组件的props选项。
(c)template:存放组件的HTML结构;并且可直接使用模板字符串“。
(d)methods:子组件触发的事件(父组件在使用子组件的地方用 v-on 来监听)。
(2)HTML元素的扩展:有些元素中不能直接使用自定义标签,可用html元素的is属性来扩展,比如你要在table标签里面存放组件,你可以用<tr is="custom-select"></tr>
(3)组件之间的通信:
父组件传递数据给子组件用的是props,那子组件要改变父组件的状态则用emit events 来进行触发
代码块
Html
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="./style.css">
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<div style="float: left;">
<h2>自定义的下拉框</h2>
<custom-select btn="查询" v-bind:list="list1"></custom-select>
</div>
<div style="float:left;">
<h2>自定义的下拉框2</h2>
<custom-select btn="搜索" v-bind:list="list2"></custom-select>
</div>
</div>
CSS
body{
margin:0;
font-family:"微软雅黑";
}
ul,li{
margin:0;
padding:0;
list-style:none;
}
input{
outline:none;
cursor: pointer;
}
.clearFix:after{
display: block;
content:'';
clear:both;
}
.warp{
width: 348px;
padding:100px 76px 50px;
margin:50px;
background:no-repeat;
background-color: #fd635e;
box-shadow:2px 2px 10px #6789ad;
}
.searchIpt{
position: relative;
width: 336px;
border:1px solid #3736ae;
padding:5px;
border-radius:24px;
background: #e4e4fe;
}
.searchIpt input{
line-height: 34px;
border-radius:18px;
}
.searchIpt input:nth-of-type(1){
float: left;
width: 228px;
padding-left: 40px;
border:1px solid #c9c9d5;
background: #d9d9e2;
}
.searchIpt input:nth-of-type(2){
float: right;
width: 58px;
height: 36px;
border:1px solid #fd635e;
background: #fd635e;
}
.searchIpt span{
position: absolute;
top:12px;
left: 15px;
width: 23px;
height: 23px;
background: url(images/select_search.png) no-repeat;
}
.searchIpt input:nth-of-type(1):focus{
background: #fff;
border-color:#fd635e;
}
.list{
margin-top:9px;
}
.list li{
margin:3px 0;
color:#333;
line-height: 30px;
padding-left: 16px;
width: 270px;
box-sizing:border-box;
border-radius:14px;
}
.list li.active,.list li:hover{
color:#fff;
background: #fd635e;
cursor: pointer;
}
js
<script>
//注册组件
Vue.component("custom-select",{
data:function(){
return {
selectShow:false,
val:""
};
},
props:["btn","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="btn">
<span></span>
</div>
<custom-list
v-show="selectShow"
:list="list"
v-on:receive="changeValueHandle"
></custom-list>
</div>
</section>`,
methods:{
changeValueHandle(value){
this.val = value;
}
}
})
Vue.component("custom-list",{
props:["list"],
template:`<ul class="list">
<li v-for="item of list" @click="selectValueHandle(item)">{{item}}</li>
</ul>`,
methods:{
selectValueHandle:function(item){
//在子组件中有交互
//告知父级,改变val的值,需要出发一个自定义事件
this.$emit("receive",item);
}
}
})
new Vue({
el:"#app",
data:{
list1:["深圳","广州","北京","上海","杭州"],
list2:["html","css","js","jq","vue","react"]
}
});
</script>