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刪除。