Files
zyt/admin/src/components/medicine-name-select/index.vue
T
2026-03-27 18:06:12 +08:00

97 lines
2.1 KiB
Vue

<template>
<span v-if="disabled" class="medicine-name-readonly">{{ modelValue || '—' }}</span>
<el-select
v-else
:model-value="modelValue"
class="medicine-name-select w-full"
filterable
remote
reserve-keyword
placeholder="搜索药材名称或拼音首字母"
:remote-method="remoteMethod"
:loading="loading"
clearable
@visible-change="onVisibleChange"
@update:model-value="onUpdate"
>
<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.name" />
</el-select>
</template>
<script setup lang="ts">
import { medicineLists } from '@/api/medicine'
const props = withDefaults(
defineProps<{
modelValue: string
disabled?: boolean
}>(),
{ disabled: false }
)
const emit = defineEmits<{
'update:modelValue': [value: string]
}>()
const loading = ref(false)
const options = ref<{ id: number; name: string }[]>([])
function ensureCurrentInOptions() {
const v = (props.modelValue || '').trim()
if (!v) {
return
}
if (!options.value.some((o) => o.name === v)) {
options.value = [{ id: 0, name: v }, ...options.value]
}
}
const remoteMethod = async (query: string) => {
loading.value = true
try {
const q = (query || '').trim()
const res = await medicineLists({
name: q || undefined,
page_no: 1,
page_size: 100,
status: 1
})
options.value = res.lists || []
ensureCurrentInOptions()
} catch (e) {
console.error(e)
options.value = []
} finally {
loading.value = false
}
}
const onVisibleChange = (open: boolean) => {
if (open && options.value.length === 0) {
remoteMethod('')
}
}
const onUpdate = (val: string) => {
emit('update:modelValue', val || '')
}
watch(
() => props.modelValue,
() => {
ensureCurrentInOptions()
},
{ immediate: true }
)
</script>
<style scoped lang="scss">
.medicine-name-readonly {
color: var(--el-text-color-regular);
}
.medicine-name-select.w-full {
width: 100%;
}
</style>