123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- <template>
- <div>
- <van-field v-model="text" v-bind="$attrs" readonly is-link :name="name" :label="label" @click="show = !show" :rules="rules" :required="required" />
- <van-popup :show="show" round position="bottom">
- <van-search v-if="search" v-model="keyWord" placeholder="请输入搜索关键词" />
- <van-picker v-model="selectedValues" :columns="filterColumns" :column-field-names="customFieldName" show-toolbar :title="label" @cancel="show = false, keyWord = null" @confirm="onConfirm">
- <template #empty>
- <van-empty :image="emptyImage" image-size="80" description="暂无数据" />
- </template>
- </van-picker>
- </van-popup>
- </div>
- </template>
- <script>
- import emptyImage from '@/assets/images/custom-empty-image.png';
- import { ref, watch, nextTick } from 'vue';
- import { Field, Popup, Picker } from 'vant';
- export default {
- components: {
- 'van-field': Field,
- 'van-popup': Popup,
- 'van-picker': Picker,
- },
- props: {
- // 传入组件的下拉选项原始数组
- columns: {
- type: Array,
- required: true,
- },
- // 表单项
- label: String,
- // 父组件绑定值
- modelValue: String,
- // 自定义 columns 结构中的字段, 结构不一样就调用组件时传入新的格式, 不然组件无法解析
- customFieldName: {
- type: Object,
- // 默认选项格式
- default: () => ({
- text: 'text',
- value: 'value',
- }),
- },
- // 组件name
- name: String,
- // 校验规则
- rules: Array,
- // 是否显示*标
- required: Boolean,
- // 是否开启搜索功能
- search: {
- type: Boolean,
- default: false,
- },
- },
- data() {
- return {
- // 空状态图片
- emptyImage,
- // 用于操作的下拉选项数组(如筛选等)
- filterColumns: [],
- // 选择的选项
- selectedValues: [],
- // 组件可见状态
- show: false,
- // 显示文本
- text: '',
- // 选择的值
- code: '',
- // 搜索关键词
- keyWord: null,
- };
- },
- watch: {
- modelValue(newVal) {
- this.reShow();
- },
- columns(newVal) {
- this.filterColumns = newVal;
- this.reShow();
- },
- code(newVal) {
- // 更新绑定值
- this.$emit('update:modelValue', newVal);
- // 传回change事件
- this.$emit('change', this.code);
- },
- // 监听搜索关键字的变化
- keyWord(newVal) {
- const results = [];
- this.columns.forEach((item) => {
- if (item.text.indexOf(newVal) > -1) {
- results.push(item);
- }
- });
- this.filterColumns = results;
- },
- },
- mounted() {
- this.filterColumns = this.columns;
- nextTick(() => {
- this.reShow();
- });
- },
- methods: {
- // 确认选择后触发的方法
- onConfirm({ selectedOptions }) {
- // 重置关键字
- this.keyWord = null;
- this.text = selectedOptions[0][this.customFieldName.text];
- this.code = selectedOptions[0][this.customFieldName.value];
- this.show = false;
- },
- // 回显方法
- reShow() {
- // 判断传入的modelValue是否为空
- if (this.modelValue) {
- // 不为空正常给值
- this.filterColumns.forEach((column) => {
- if (column[this.customFieldName.value] === this.modelValue) {
- this.text = column[this.customFieldName.text];
- // 主要是解决父级修改v-model绑定的值之后,组件中没联动变化
- this.selectedValues[0] = column[this.customFieldName.value];
- }
- });
- } else {
- // 为空需要清空组件中之前选择的数据
- this.text = '';
- this.code = '';
- this.selectedValues = [];
- }
- },
- },
- };
- </script>
|