捕梦者基础前端框架
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

131 lines
3.3 KiB

<!-- 字典组件 -->
<template>
<template v-if="type === 'text'">
<span v-for="item in valueData" :key="item.dictDataCode">
{{ item.dictDataName }}
</span>
</template>
<template v-else-if="type === 'tag'">
<el-tag
v-for="item in valueData"
:key="item.dictDataCode"
:disable-transitions="true"
size="small"
>
{{ item.dictDataName }}
</el-tag>
</template>
<el-radio-group
v-else-if="type === 'radio'"
:disabled="disabled"
@update:modelValue="updateValue"
:model-value="modelValue as SingleValue"
>
<el-radio
v-for="item in data"
:key="item.dictDataCode"
:value="item.dictDataCode"
:label="item.dictDataName"
/>
</el-radio-group>
<el-checkbox-group
v-else-if="type === 'checkbox'"
:disabled="disabled"
@update:modelValue="updateValue"
:model-value="modelValue as any"
>
<el-checkbox
v-for="item in data"
:key="item.dictDataCode"
:value="item.dictDataCode"
:label="item.dictDataName"
/>
</el-checkbox-group>
<el-select
v-else
@update:modelValue="updateValue"
:model-value="modelValue"
:clearable="true"
:disabled="disabled"
:placeholder="placeholder"
:multiple="type === 'multipleSelect'"
:teleported="teleported"
:filterable="filterable"
class="ele-fluid"
>
<el-option
v-for="item in data"
:key="item.dictDataCode"
:value="item.dictDataCode"
:label="item.dictDataName"
/>
</el-select>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
import { useDictData } from '@/utils/use-dict-data';
import type { DictionaryData } from '@/api/system/dictionary-data/model';
type SingleValue = string | number | boolean;
type MultipleValue = Array<SingleValue>;
type TypeValue =
| 'text'
| 'tag'
| 'radio'
| 'select'
| 'checkbox'
| 'multipleSelect';
const emit = defineEmits<{
(e: 'update:modelValue', value?: SingleValue | MultipleValue | null): void;
}>();
const props = withDefaults(
defineProps<{
/** 字典值 */
modelValue?: SingleValue | MultipleValue;
/** 字典类型 */
code: string;
/** 组件类型 */
type?: TypeValue;
/** 是否禁用 */
disabled?: boolean;
/** 提示文本 */
placeholder?: string;
/** select的下拉是否插入到body下 */
teleported?: boolean;
/** select是否可搜索 */
filterable?: boolean;
}>(),
{
teleported: true
}
);
/** 字典数据 */
const [data] = useDictData([props.code]);
/** 绑定值对应的字典数据 */
const valueData = computed<DictionaryData[]>(() => {
const result: DictionaryData[] = [];
const val = props.modelValue;
if (val == null || val === '') {
return result;
}
const values: MultipleValue = Array.isArray(val) ? val : [val];
values.forEach((v) => {
const temp = data.value.find((d) => d.dictDataCode == v);
if (temp != null) {
result.push(temp);
} else {
result.push({ dictDataCode: v as string, dictDataName: v as string });
}
});
return result;
});
/** 更新选中数据 */
const updateValue = (value?: SingleValue | MultipleValue) => {
emit('update:modelValue', value);
};
</script>