之前做了一个单页面的单选和多选,这里我整理了一下,封装成组件,能够同时支持单选和多选。
我这里的代码是在vue脚手架(vue-cli)上开发完成的,搭建方法这里就不细说了。
这个组件的名字呢命为 option.vue
option.vue
HTML:
<div class="chooser"> <ul class="chooser-list"> <li :style="cssStyle" v-for="(item, index) in options" :key="index" @click="optionsClick(item)" :class="{active: checkActive(item)}" >{{ item }}</li> </ul> </div>
CSS:
ul, li { margin: 0; padding:0; list-style: none; } .chooser { position: relative; display: inline-block; } .chooser-list li{ margin: 5px; 80px; height: 40px; line-height: 40px; border-radius: 7px; display: inline-block; border: 1px solid #9C9C9C; color: #9C9C9C; text-align: center; background: #fff; } .chooser-list li.active { border-color: #097fe0; color: #097fe0; background: #fff; }
JS:
export default { name: 'options', data () { return { currValArr: [] } }, props: { options: Array, //传入的数组 isMultiply: { //是否是多选。默认为false:单选;true:多选 type: Boolean, default: false }, cssStyle: Object //可以自定义单选或者多选的样式 }, methods: { optionsClick (item) {
},
checkActive (item) {
}
}
}
到这里为止呢,我们需要把两个方法里的逻辑补齐。
optionClick(),这个方法要实现点击然后选中,传的参数是当前数组值,在里面我们需要判断是单选还是多选
optionsClick (item) { if (this.isMultiply === false) { //单选 this.$set(this.currValArr, 0, item) // 将该值设为当前数组的第一项 } else { //多选 if (this.currValArr.indexOf(item) === -1) { // 当前数组中没有该值则push到数组 this.currValArr.push(item) } else { //当前数组中有该值,找到该值下标并删除 this.currValArr.splice(this.currValArr.indexOf(item), 1) } } }
那么在checkActive方法中,需要得到一个布尔值,来确定是否添加类名active
checkActive (item) { if (this.isMultiply === false) { this.currValArr.length = 1 } return this.currValArr.indexOf(item) !== -1 }
App.vue
<template> <div id="app"> <h3>单选</h3> <options :options="selections"></options> <h3>多选</h3> <options :options="selections1" :isMultiply=true></options> </div> </template> <script> import Options from './components/options'; //注意这里的路径 export default { name: 'App', components: { Options }, data () { return { selections: ['赵雅芝','刘雪华','俞飞鸿','林青霞','陈美琪'], selections1: ['慕容冲','潘安','宋玉','卫玠','兰陵王'] } }, } </script>
效果图如下:
虽然现在看上去基本OK了,单选多选都能实现,但我们还希望他能实现双向绑定,现在视图可以更新数据,我们接下来完成数据更新视图
App.vue 中,
template:
<options :options="selections" v-model="value"></options>
<div>当前选中值:{{value}}</div>
<options :options="selections1" v-model="value1" :isMultiply=true></options>
<div>当前选中值:{{value1}}</div>
js:
data () { return { // 代码省略 value: ['赵雅芝'], value1: ['卫玠','潘安',] } }
option.vue中
export default { name: 'options', model: { prop: 'currValArr', event: 'input' }, props: { currValArr: Array, options: Array, isMultiply: { type: Boolean, default: false }, cssStyle: Object }, methods: { // ... } }
这样,就实现了双向绑定了。使用了自定义组件的v-model,利用model选项,来指定prop和event。不了解自定义组件model的可以去官网看,上面讲解的很详细。