下面是效果图
经过几天的vue学习,终于可以自己动手完成一个像样的组件了,下面是具体的过程
首先我们先书写template结构
<template>
<div id="demo03">
<div class="header">
<h1>第一个组件:下拉框组件</h1>
</div>
<div class="content">
<div class="component">
<Selected :optionData="optionData"></Selected>
</div>
</div>
</div>
</template>
这是展示效果的模板结构,真正的下拉框组件用Selected标签来展现,
展示的数据如下
<script>
import Selected from '../../components/Select/select.vue'
export default{
data () {
return {
optionData: [{
value: 1,
text: '牛奶'
},{
value: 2,
text: '面包'
},{
value: 3,
text: '美女'
}],
}
},
components: {
Selected
}
}
</script>
把optionData绑定到Selected里,以达到数据变化复用的效果,
<template>
<div class="select-component">
<div class="select-input">
<input type="text" placeholder="请选择" readonly="readonly" v-model="selected.text" autocomplete="off" class="el-input__inner" @click="dropDown">
<div class="icon">
<div class="icon-warrp" :class="{roate: classRoate}">
<span class="select-icon"></span>
</div>
</div>
</div>
<div class="select-options" :class="{show: classShow}">
<ul>
<li class="select-options-item" v-for="(item, index) in optionData" :class="{selected: classSelected == index}" @click="selectItem(index)">{{item.text}}</li>
</ul>
</div>
</div>
</template>
下拉框的具体的结构如上,就是一个input来承载value,一个无序列表来装下拉项,
具体的逻辑如下
<script>
export default {
data () {
return {
classShow: false,
classRoate: false,
selected: {
value: '',
text: ''
},
classSelected: -1,
}
},
props:['optionData'],
methods: {
dropDown () {
if(this.classShow){
this.classShow = false
this.classRoate = false
}else{
this.classShow = true
this.classRoate = true
}
},
selectItem (index) {
this.selected = this.optionData[index]
this.classSelected = index
this.classShow = false
this.classRoate = false
}
}
}
</script>
就是利用props来接受外界传进来的数据,然后进行渲染。
“`
.select-component
width 240px
& .select-input
position relative
font-size 14px
display inline-block
width 100%
cursor pointer
& .el-input__inner
appearance none
background-color #fff
background-image none
border-radius 4px
border 1px solid #bfcbd9
box-sizing border-box
color #1f2d3d
display block
font-size inherit
height 36px
line-height 1
outline none
padding 3px 10px
transition border-color .2s cubic-bezier(.645,.045,.355,1)
width 100%
cursor pointer
.el-input__inner:hover
border: 1px solid #999
.icon
position absolute
right 8px
top 6px
width 24px
height 24px
line-height 24px
overflow hidden
.icon-warrp
width 100%
height 100%
position relative
transition transform .2s cubic-bezier(.645,.045,.355,1)
.select-icon
position absolute
right 50%
top 50%
margin-right -8px
margin-top -4px
width 0
height 0
border-width 8px 8px 0
border-style solid
border-color #bfcbd9 transparent transparent
.roate
transform rotate(180deg)
.select-options
width 224px
background #fff
border 1px solid #bfcbd9
margin-top 8px
padding 8px
opacity 0
& ul
list-style: none;
padding: 6px 0;
margin: 0;
box-sizing: border-box;
.select-options-item
font-size 14px
padding 8px 10px
position relative
white-space nowrap
overflow hidden
text-overflow ellipsis
color #48576a
height 36px
line-height 1.5
box-sizing border-box
cursor pointer
.select-options-item.selected
color #fff
background-color #20a0ff
.show
animation 0.3s fadeInShow
animation-fill-mode: forwards;
@keyframes fadeInShow
0%
opacity 0
transform translateY(-5px)
100%
opacity 1
transform translateY(0)
第一次用stylus,不会语法,瞎写的,抽时间学习下先,哈哈~~~
目前还没有加上绑定事件, 话说用 this.$emit就可以分发事件了,有时间完善下,加上诸如原生组件的onChang,click事件等等。
github地址:https://github.com/CavinHuang/vue-study/tree/master/coffee/src/pages/demo03