<template> <van-popup :show="show" position="bottom" :teleport="teleport" class="input-select"> <van-picker title="请选择或录入" :columns="array" :columns-field-names="fieldNames" v-model="innerValue" @confirm="onConfirm" @cancel="onCancel" > <template #columns-top> <van-field v-model="customValue" placeholder="请输入" clearable maxlength="100"/> </template> </van-picker> </van-popup> </template> <script> export default { props: { show: Boolean, value: [String, Number], fieldNames: { type: Object, default: () => { return {text: 'name', value: 'value'} } }, // 字典 dict: { type: Array, required: true }, teleport: [String, Element] }, emits: ['update:show', 'update:value', 'change'], data() { return { innerValue: undefined, customValue: '' } }, computed: { array() { const array = this.dict || [] const result = array.filter(e => e.value.startsWith(this.customValue)) if (result.length) { return [...result] } return [{ [this.fieldNames.text]: this.customValue, [this.fieldNames.value]: this.customValue }] } }, methods: { onConfirm({ selectedValues, selectedOptions }) { this.$emit('update:value', selectedValues[0]) this.$emit('change', selectedOptions[0] || {}) this.$emit('update:show', false) this.customValue = '' }, onCancel() { this.$emit('update:show', false) } }, watch: { value: { handler(value) { if (value == null) return this.innerValue = [value] }, immediate: true }, } } </script> <style lang="less" scoped> </style>