因为vant2的下拉列表需要input框和弹框组合使用,所以自己封装了一下,点击确定可以返回选择的对象,并且支持多个下拉列表共用一个确定方法。 组件的特点:
- 点击显示下拉列表的弹框,点击确定给父组件返回选中的内容,包括
text(选中的文字内容)和value(选中的值); - 当页面有多个下拉框的时候,可以共用
confirm方法,从而简化代码; - 支持下拉列表默认回显功能
组件内容
1<template> 2 <div class="pickerPop"> 3 <van-field 4 readonly 5 clickable 6 :required="required" 7 :name="fieldName" 8 :value="fieldValueText" 9 :label="fieldLabel" 10 :rules="rules" 11 placeholder="请选择" 12 @click="showPicker = true" 13 /> 14 <van-popup v-model="showPicker" position="bottom"> 15 <van-picker 16 :title="defaultTitle" 17 v-model="selectedValue" 18 :default-index="selectedIndex" 19 show-toolbar 20 value-key="text" 21 :columns="columns" 22 @confirm="(value) => onConfirm(fieldType, value)" 23 @cancel="showPicker = false" 24 /> 25 </van-popup> 26 </div> 27 28</template> 29 30<script> 31/* 32* 1、这是个封装的下拉列表组件, 33* 如果需要显示默认值需要在组件上写 v-if="isDictRender" defaultValue="你的默认显示的下拉框的值" 34* v-if是必须的,否则赋值和获取列表数据是异步,无法回显 35* 2、如果一个页面多次需要这个组件,可以传入fieldType="你的下拉框类型" 36* 这样的话需要复用的下拉框的确定事件就可以写一个如 @confirm="onConfirm" 37* 共用onConfirm()方法,根据返回值返回的type字段进行区分 38* 39* */ 40export default { 41 name: 'pickerPop', 42 props: { 43 // 如果有多个下拉框存在的时候可以用这个判断 44 fieldType: { 45 type: String, 46 default: '' 47 }, 48 // 前面红色*号 49 required: { 50 type: Boolean, 51 default: false 52 }, 53 // 验证 54 rules: { 55 type: Array, 56 }, 57 // 提交表单的标识符 // 根据你的需求,可以不传 58 fieldName: { 59 type: String, 60 default: '' 61 }, 62 // 标题 63 defaultTitle: { 64 type: String, 65 default: '' 66 }, 67 // label显示的文字 68 fieldLabel: { 69 type: String, 70 default: '' 71 }, 72 // 传进来的默认值 73 defaultValue: { 74 type: [String, Number], // 根据你的需求定义类型 75 default: null, 76 }, 77 // 要显示的文字 如果要做回显就给这个值赋值 78 fieldValueText: { 79 type: String, 80 default: '' 81 }, 82 // 下拉列表数据 83 columns: { 84 type: Array, 85 required: true 86 } 87 }, 88 data() { 89 return { 90 showPicker: false, 91 selectedValue: this.defaultValue, // 使用 prop 的默认值来初始化 selectedValue 92 selectedIndex: '', // 默认回显 93 }; 94 }, 95 created(){ 96 97 }, 98 mounted(){ 99 // 根据默认值获取当前数据所在字典表数组的索引 100 this.selectedIndex = this.columns.findIndex((item) => item.value == this.defaultValue) 101 }, 102 computed: {}, 103 methods: { 104 onConfirm(type, value) { 105 // console.log('Type:', type); // 输出 'Type' 106 // console.log('Value:', value); // 输出选中的值 107 /* 108 * 返回的这个type是根据组件传入的参数, 109 * 当有多个下拉框存在的时候用这个组件可以用一个confirm方法通过type进行判断, 110 * 不用再多写很多确定事件了 111 * */ 112 this.$emit('confirm', { 113 type: type?type:null, 114 text: value.text, 115 value: value.value 116 }); 117 this.showPicker = false; 118 } 119 } 120}; 121</script> 122<style scoped lang="less"> 123.van-cell--borderless:after, .van-cell:last-child:after { 124 display: initial; 125} 126</style> 127
父组件这样使用:
1<template> 2 <div class="box"> 3 <pickerPop 4 v-if="isDictRender" 5 defaultValue="O" 6 fieldName="bloodTypeText" 7 fieldLabel="血型" 8 :fieldValueText="bloodTypeText" 9 :columns="columns_blood" 10 defaultTitle="血型" 11 @confirm="onConfirm" 12 /> 13 </div> 14</template> 15 16<script> 17export default { 18 data() { 19 return { 20 isDictRender: false, 21 bloodValue: '', // 血型 22 bloodTypeText: '', // 血型-文字 23 // 血型字典表 24 columns_blood: [ 25 { text: 'A型', value: 'A' }, 26 { text: 'B型', value: 'B' }, 27 { text: 'AB型', value: 'AB' }, 28 { text: 'O型', value: 'O' }, 29 ] 30 } 31 }, 32 methods: { 33 // 血型确定 34 onConfirm(value) { 35 console.log(value) 36 this.bloodTypeText = value.text; 37 this.bloodValue = value.value; 38 }, 39 }, 40 created() { 41 42 } 43} 44</script> 45 46<style scoped> 47 48</style> 49
