80 lines
1.8 KiB
Vue
80 lines
1.8 KiB
Vue
<template>
|
|
<el-select style="width: 100%" v-model="state.selectId" :placeholder="props.placeholder" clearable
|
|
:multiple="props.multiple" @visible-change="(e: boolean) => e && getDictOptions()">
|
|
<el-option v-for="v in filterDictList" :key="v.code" :label="v.label" :value="v.value" />
|
|
</el-select>
|
|
</template>
|
|
|
|
<script setup lang="ts" name="dict-select">
|
|
import { reactive } from "vue"
|
|
import { dict } from "/@/stores/dict"
|
|
import { getDicts } from "/@/api/admin/dict"
|
|
|
|
const selectId = defineModel()
|
|
|
|
export type Props = {
|
|
dictCode: string
|
|
placeholder?: string
|
|
hideIds?: string | Array<string>
|
|
multiple?: boolean
|
|
}
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
placeholder: "请选择",
|
|
multiple: false,
|
|
})
|
|
|
|
const state = reactive<any>({
|
|
selectId: selectId,
|
|
dictList: [],
|
|
})
|
|
|
|
watch(
|
|
selectId,
|
|
(newVal, oldValue) => {
|
|
if (newVal == oldValue) return
|
|
state.selectId = newVal
|
|
getDictOptions()
|
|
},
|
|
{ immediate: true },
|
|
)
|
|
|
|
const filterDictList = computed(() => {
|
|
const hideKeys = props.hideIds
|
|
// 排序
|
|
const list = state.dictList?.sort((pren: any, next: any) => {
|
|
return pren.sortOrder - next.sortOrder
|
|
})
|
|
if (!hideKeys) return list
|
|
if (typeof hideKeys == "string") {
|
|
return list.filter((p: any) => p.value != hideKeys)
|
|
}
|
|
if (Array.isArray(hideKeys)) {
|
|
return list.filter((p: any) => !hideKeys.includes(p.value))
|
|
}
|
|
})
|
|
|
|
async function getDictOptions() {
|
|
if (!props.dictCode) return []
|
|
const dicts = dict().getDict(props.dictCode)
|
|
if (dicts) {
|
|
state.dictList = dicts
|
|
return
|
|
}
|
|
const res = await getDicts(props.dictCode)
|
|
if (!res) return []
|
|
state.dictList = res.data.map((p: any) => ({
|
|
label: p.label,
|
|
value: p.value,
|
|
elTagType: p.listClass,
|
|
elTagClass: p.cssClass,
|
|
}))
|
|
dict().setDict(props.dictCode, state.dictList)
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.el-tag+.el-tag {
|
|
margin-left: 10px;
|
|
}
|
|
</style>
|