<!-- 可输入配置字典的下拉选项 输入框 --> <script lang="ts" setup name="SelectByDict"> import { CircleClose } from '@element-plus/icons-vue' import { getDictAllList, getDictByCode, updateDict } from '@/api/system/dict' // ------------------定义props、 emit------------------- const props = defineProps({ // 数据绑定 modelValue: { type: [Number, String], default: '', }, // 输入 // 是否禁用 disabled: { type: Boolean, default: false, }, placeholder: { type: String, default: '请输入', }, // 字典纸对应code dictCode: { type: String, required: true, }, }) const emit = defineEmits(['update:modelValue', 'getDictValue']) // -------------------------定义数据-------------------- const value = computed({ get() { return props.modelValue }, set(value) { emit('update:modelValue', value) }, }) // 点击选项 const handleSelect = (item: LinkItem) => { // console.log(item) } // 字典列表 const dictList = ref<{ name: string;id: string;value: string }[]>([]) // 获取字典列表 const fetchDict = () => { getDictByCode(props.dictCode).then((res) => { dictList.value = res.data.map((item: any) => ({ ...item, value1: item.value, value: item.name })) }) } // 加载选项数据 const querySearch = (queryString: string, cb) => { const results = queryString ? dictList.value.filter(item => item.name.includes(queryString)) : dictList.value cb(results) } // 数据转换, 字典详情转换为中间带冒号的 function arrayToString(arr: any[]) { let detailArray = '' const detailList = arr detailList.forEach((detail, index) => { detailArray += `${detail.value}:${detail.name}:${detail.num}` if (index !== (detailList.length - 1)) { detailArray += ';' } }) return detailArray } // 字典详情字符串转数组 function stringToArray(data: string) { const detailArr = data.split(';') const arr = [] for (const detail of detailArr) { const detailItem = detail.split(':') const item = { value: detailItem[0], name: detailItem[1], num: parseInt(detailItem[2]), } arr.push(item) } return arr } // 更新字典 const updateDictFun = () => { if (value.value) { const inputValue = value.value // 先判断字典中是否存在该值 const data = dictList.value.filter(item => item.name === inputValue).length if (!data) { console.log(inputValue, '该值不存在添加字典') // 在字典中添加该值 getDictAllList().then((res) => { const currentDict = res.data.filter(item => item.code === props.dictCode)[0] // 整理数据 const formData = { dictId: currentDict.id, dictCode: currentDict.code, dictName: currentDict.name, dictTips: currentDict.tips, dictValues: currentDict.detail, } const dict = stringToArray(formData.dictValues) // 在原来数据中插入新的数据 dict.push({ value: dict.map(item => item.value).every(item => !isNaN(item)) ? String(Math.max(...dict.map(item => Number(item.value))) + 1) : String(Math.ceil(Math.random() * 1000)), name: inputValue, num: dict[dict.length - 1].num + 1, }) formData.dictValues = arrayToString(JSON.parse(JSON.stringify(dict))) // 调用更新接口 updateDict(formData).then(() => { // 更新字典列表 dictList.value = dict.map((item: any) => ({ ...item, value1: item.value, value: item.name })) // 发送 绑定的value (可用可不用) emit('getDictValue', dictList.value.filter(item => item.name === inputValue)[0].value1) }) }) } else { console.log(inputValue, '该值存在') // 发送 绑定的value (可用可不用) emit('getDictValue', dictList.value.filter(item => item.name === inputValue)[0].value1) } } } // -------------------------钩子-------------------- onMounted(() => { if (props.dictCode) { fetchDict() } }) // defineExpose({ // clearMulti, initColumnsState, // }) </script> <template> <el-autocomplete v-model.trim="value" clearable :fetch-suggestions="querySearch" :disabled="props.disabled" popper-class="my-autocomplete" :placeholder="props.placeholder" style="width: 100%;" @select="handleSelect" @blur="updateDictFun" > <template #default="{ item }"> <div class="value"> <div>{{ item.name }}</div> <div /> <!-- <div style="height: 34px;line-height: 40px;"> <el-icon style="font-size: 18px;"> <circle-close /> </el-icon> </div> --> </div> </template> </el-autocomplete> </template> <style scoped lang="scss"> .value { display: flex; justify-content: space-between; line-height: 34px; } </style>