feat: 新增字典和字典展示功能

新增字典和字典展示功能
This commit is contained in:
Theo
2024-11-24 15:46:25 +08:00
parent 93507af63a
commit 1f8cda13b9
12 changed files with 431 additions and 16 deletions

View File

@@ -0,0 +1,54 @@
<template>
<template v-if="tagType">
<wd-tag :type="tagType" :round="round">{{ label }}</wd-tag>
</template>
<template v-else>
<view>{{ label }}</view>
</template>
</template>
<script setup lang="ts">
import { useDictStore } from "@/store/modules/dict";
const dictStore = useDictStore();
const props = defineProps({
code: String,
modelValue: [String, Number],
round: {
type: Boolean,
default: false,
},
});
type TagType = "success" | "warning" | "primary" | "danger" | "default";
const label = ref("");
const tagType = ref<TagType>();
const getLabelAndTagByValue = async (dictCode: string, value: any) => {
// 先从本地缓存中获取字典数据
const dictData = dictStore.getDictionary(dictCode);
console.log("dictData", dictData);
// 查找对应的字典项
const dictEntry = dictData.find((item: any) => item.value == value);
return {
label: dictEntry ? dictEntry.label : "",
tag: dictEntry ? dictEntry.tagType : undefined,
};
};
// 监听 props 的变化,获取并更新 label 和 tag
const fetchLabelAndTag = async () => {
const result = await getLabelAndTagByValue(props.code as string, props.modelValue);
console.log("result", result);
label.value = result.label;
if (result.tag === "info") {
result.tag = "default";
}
tagType.value = result.tag as "success" | "warning" | "primary" | "danger" | "default";
};
// 首次挂载时获取字典数据
onMounted(fetchLabelAndTag);
// 当 modelValue 发生变化时重新获取
watch(() => props.modelValue, fetchLabelAndTag);
</script>

View File

@@ -0,0 +1,126 @@
<template>
<wd-picker
v-if="type === 'select' || type === 'radio'"
v-model="selectedValue"
:columns="options"
:label="label"
:placeholder="placeholder"
clearable
:rules="rules"
@confirm="handleChange"
/>
<wd-select-picker
v-else-if="type === 'checkbox'"
v-model="selectedValue"
:columns="options"
:placeholder="placeholder"
clearable
:label="label"
:rules="rules"
@confirm="handleChange"
/>
<wd-input
v-else
v-model="selectedValue"
:label="label"
clearable
:placeholder="placeholder"
:rules="rules"
@input="handleChange"
/>
</template>
<script setup lang="ts">
import { useDictStore } from "@/store/modules/dict";
const dictStore = useDictStore();
const props = defineProps({
code: {
type: String,
required: true,
},
modelValue: {
type: [String, Number, Array],
required: false,
},
label: {
type: String,
default: "",
},
type: {
type: String,
default: "select",
validator: (value: string) => ["select", "radio", "checkbox"].includes(value),
},
placeholder: {
type: String,
default: "请选择",
},
disabled: {
type: Boolean,
default: false,
},
rules: {
type: Array as PropType<any[]>,
default: () => [],
},
});
const emit = defineEmits(["update:modelValue"]);
const options = ref<Array<{ label: string; value: string | number }>>([]);
const selectedValue = ref<any>(
typeof props.modelValue === "string" || typeof props.modelValue === "number"
? props.modelValue
: Array.isArray(props.modelValue)
? props.modelValue
: undefined
);
// 监听 modelValue 变化
watch(
() => props.modelValue,
(newValue) => {
if (props.type === "checkbox") {
selectedValue.value = Array.isArray(newValue) ? newValue : [];
} else {
selectedValue.value = newValue?.toString() || "";
}
},
{ immediate: true }
);
// 监听 options 变化并重新匹配 selectedValue
watch(
() => options.value,
(newOptions) => {
// options 加载后,确保 selectedValue 可以正确匹配到 options
if (newOptions.length > 0 && selectedValue.value !== undefined) {
const matchedOption = newOptions.find((option) => option.value === selectedValue.value);
if (!matchedOption && props.type !== "checkbox") {
// 如果找不到匹配项,清空选中
selectedValue.value = "";
}
}
}
);
// 监听 selectedValue 的变化并触发 update:modelValue
function handleChange(val: any) {
emit("update:modelValue", val.value);
}
// 获取字典数据
onMounted(async () => {
if (!props.type) {
return;
}
let dictData = dictStore.getDictionary(props.code);
options.value = dictData.map((item) => ({
label: item.label,
value: item.value,
}));
});
</script>