vant实现select效果,单选和多选


官方推荐picker,但是我们项目用picker还要搭配Popup和cell、field,维护太太麻烦,所以自己封装一个

select单选

//封装VanFieldSelectPicker组件 <template> <div> <van-field v-model="resultLabel" v-bind="$attrs" readonly is-link input-align="right" @click="show = !show" /> <van-popup v-model="show" position="bottom"> <van-picker v-bind="$attrs" :columns="columns" show-toolbar @cancel="cancel" @confirm="onConfirm" @change="change" :value-key="this.option.label" /> </van-popup> </div> </template> <script> export default { name: 'VanFieldSelectPicker', model: { prop: 'selectValue' }, props: { columns: { type: Array, default: function () { return [] } }, selectValue: { type: [String, Number], default: '' }, option: { type: Object, default: function () { return { label: 'label', value: 'value' } } } }, computed: { resultLabel: {//双向绑定的数据做修改需要用get/set get () { const res = this.columns.filter(item => { return item[this.option.value] === this.resultValue }) return res.length ? res[0][this.option.label] : '' }, set () { } } }, data () { return { show: false,//Popup是否弹出 resultValue: this.selectValue //初始选中数据 } }, methods: { onConfirm (value, index) {//确定 this.resultValue = value[this.option.value] this.show = !this.show this.$emit('confirm', value, index, this.resultValue) }, change (val, index) {//当数据改变 this.$emit('change', val, index, this.resultValue) }, cancel (val, index) {//取消 this.show = !this.show this.$emit('cancel', val, index, this.resultValue) } }, watch: { selectValue: function (newVal) {//监听变化初始赋值 this.resultValue = newVal }, resultValue (val) {//当所选数据变化,组件model的双向绑定 this.$emit('input', val) } } } </script> <style></style> 

使用(建议全局注册)

<van-field-select-picker label="单选select" placeholder="请选择" v-model="value1" :columns="columns" :option="{label:'name',value:'code'}" @confirm="confirm2" /> data: value1: '1', // select选中的value columns: [// 如果可选数据不是label-value,需要配置下option,如果是就不需要配置 { name: '我是选中的label', code: '1', other: '额外数据' }, { name: '我也是选中的label33333', code: '2', other: '额外数据' }, { name: '我是选中的label', code: '21', other: '额外数据' }, { name: '我也是选中的label555555555', code: '22', other: '额外数据' }, { name: '我是选中的label', code: '11', other: '额外数据' }, { name: '我也是选中的label', code: '52', other: '额外数据' }, { name: '我是选中的label', code: '71', other: '额外数据' }, { name: '我也是选中的label', code: '72', other: '额外数据' } ] methods: confirm2 (data1, index, data2) { // checkbox确定, // tips 正常获取值,用不到这个方法,用v-model获取值即可,这个方法是告诉你,可以获取任何你想要的数据 // data1 当前这一条的obj数据 // index 当前选择的索引 // data2 当前这一条数据的value console.log(data1, data2, index) this.value4 = data1 } 

Events 同 vant-picker

|-confirm -- 点击完成按钮时触发 -- 单列:选中[整个数据]的值,选中值对应的索引,选中的value-|
|-cancel -- 点击取消按钮时触发 -- 单列:选中[整个数据]的值,选中值对应的索引,选中的value-|
|-change -- 选项改变时触发 -- 单列:选中[整个数据]的值,选中值对应的索引,选中的value-|

属性

label-width ---------------------------label的一个宽度设置

label="单选select"---------------------label文字

:columns="columns"---------------------可选择的数据,只接受key-value格式的对象集合,[1,2,3]不可以

:option="{label:'name',value:'code'}"--数据的配置格式,默认label(显示的文字),value(具体值)

checkbox多选

//封装VanFieldCheckbox组件
<template> <div> <van-field v-model="resultLabel" v-bind="$attrs" readonly is-link input-align="right" @click="show = !show" /> <van-popup v-model="show" position="bottom" class="" > <div class="van-picker__toolbar"> <button type="button" class="van-picker__cancel" @click="cancel">取消</button> <div class="van-ellipsis van-picker__title">{{$attrs.label}}</div> <button type="button" class="van-picker__confirm" @click="onConfirm">确认</button> </div> <div class="checkbox-con" style="max-height:264px;overflow-y:auto"> <van-cell title="全选"> <template #right-icon> <van-checkbox name="all" @click="toggleAll" v-model="checkedAll"/> </template> </van-cell> <van-checkbox-group v-model="checkboxValue" @change="change" ref="checkboxGroup"> <van-cell-group> <van-cell v-for="(item, index) in columns" clickable :key="item[option.value]" :title="item[option.label]" @click="toggle(index)" > <template #right-icon> <van-checkbox :name="item[option.value]" ref="checkboxes" /> </template> </van-cell> </van-cell-group> </van-checkbox-group> </div> </van-popup> </div> </template> <script> export default { name: 'VanFieldCheckbox', model: { prop: 'selectValue' }, props: { columns: { type: Array, default: function () { return [] } }, selectValue: { type: Array, default: function () { return [] } }, option: { type: Object, default: function () { return { label: 'label', value: 'value' } } } }, computed: { resultLabel: { get () { const res = this.columns.filter(item => { return this.resultValue.indexOf(item[this.option.value]) > -1 }) const resLabel = res.map(item => { return item[this.option.label] }) return resLabel.join(',') }, set () { } } }, data () { return { show: false, checkboxValue: JSON.parse(JSON.stringify(this.selectValue)), checkedAll: false, resultValue: JSON.parse(JSON.stringify(this.selectValue)) } }, methods: { getData (val) {//过滤出所选数据的obj集合 const res = this.columns.filter(item => { return val.indexOf(item[this.option.value]) > -1 }) return res }, onConfirm () {//确定 this.resultValue = this.checkboxValue this.show = !this.show this.$emit('confirm', this.resultValue, this.getData(this.resultValue)) }, change (val) {//当数据选中变化时 this.$emit('change', val, this.getData(this.resultValue)) }, cancel () {//取消 this.show = !this.show this.$emit('cancel', this.resultValue) }, toggle (index) {//cell点击事件,同步checkbox this.$refs.checkboxes[index].toggle() }, toggleAll (all) {//全选 this.$refs.checkboxGroup.toggleAll(this.checkedAll) } }, watch: { selectValue: function (newVal) { this.resultValue = newVal }, resultValue (val) { this.$emit('input', val) }, checkboxValue (val) {//监听数据变化,判断全选的状态 if (val.length !== this.columns.length) { this.checkedAll = false } else { this.checkedAll = true } } } } </script> <style> .van-cell__title{text-align: left;} </style> 

使用

 <van-field-checkbox label="多选checkbox" placeholder="请选择" v-model="value2" :columns="columns" label-width="100" :option="{label:'name',value:'code'}" @confirm="confirm" /> data: value2: ['1'], // checkbox选中的value columns: [// 如果可选数据不是label-value,需要配置下option,如果是就不需要配置 { name: '我是选中的label', code: '1', other: '额外数据' }, { name: '我也是选中的label33333', code: '2', other: '额外数据' }, { name: '我是选中的label', code: '21', other: '额外数据' }, { name: '我也是选中的label555555555', code: '22', other: '额外数据' }, { name: '我是选中的label', code: '11', other: '额外数据' }, { name: '我也是选中的label', code: '52', other: '额外数据' }, { name: '我是选中的label', code: '71', other: '额外数据' }, { name: '我也是选中的label', code: '72', other: '额外数据' } ] methods: confirm (data1, data2) { // select确定, // tips 正常获取值,用不到这个方法,用v-model获取值即可,这个方法是告诉你,可以获取任何你想要的数据 // data1 是当前选中数据的value的数组 // data2 是当前选中数据的整个obj集合 console.log(data1, data2) this.value3 = data2 }, 

Events 同 vant-picker

|-confirm -- 点击完成按钮时触发 -- 单列:选中[整个数据]的值,选中值对应的索引,选中的value-|
|-cancel -- 点击取消按钮时触发 -- 单列:选中[整个数据]的值,选中值对应的索引,选中的value-|
|-change -- 选项改变时触发 -- 单列:选中[整个数据]的值,选中值对应的索引,选中的value-|

属性

label-width ---------------------------label的一个宽度设置

label="单选select"---------------------label文字

:columns="columns"---------------------可选择的数据,只接受key-value格式的对象集合,[1,2,3]不可以

:option="{label:'name',value:'code'}"--数据的配置格式,默认label(显示的文字),value(具体值)

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM