Nuxt UI 集成
将字典模块与 Nuxt UI 组件配合使用的完整示例。
本章提供 6 个完整示例,展示字典模块与 Nuxt UI 常用组件的配合用法。
前提:项目中已安装 @nuxt/ui。
USelect 下拉选择器
useDict 返回的 { label, value }[] 与 Nuxt UI 的 items prop 直接兼容,无需转换。
<template>
<USelect v-model="value" :items="options" placeholder="请选择性别" :loading="loading" />
</template>
<script setup lang="ts">
const { options, loading } = useDict('gender');
const value = ref('');
</script>
UTable 表格列翻译
<template>
<UTable :rows="tableData" :columns="columns" />
</template>
<script setup lang="ts">
const { data: statusData } = useDict('status');
function getStatusColor(value: number) {
return (statusData.value?.find((i) => i.value === code) as any)?.color;
}
const columns = computed(() => [
{ key: 'name', label: '姓名' },
{ key: 'gender', label: '性别' },
{
key: 'status',
label: '状态',
cell: ({ row }: { row: any }) =>
h(UBadge, {
color: getStatusColor(row.status) as any,
label: $dict.translate('status', row.status) as string,
}),
},
]);
const tableData = ref([
{ name: '张三', gender: 'male', status: 1 },
{ name: '李四', gender: 'female', status: 0 },
]);
</script>
树形字典(嵌套级联选择)
Nuxt UI 没有内置 Cascader,通过 USelectMenu 的嵌套 children 属性实现级联:
<template>
<USelectMenu
v-model="selected"
:items="cascaderItems"
placeholder="请选择区域"
searchable
:loading="loading"
/>
</template>
<script setup lang="ts">
const { tree, loading, translate } = useDictTree('region');
// 转码成 USelectMenu 兼容的嵌套格式
const cascaderItems = computed(() => {
function convert(nodes: any[]): any[] {
return nodes.map((n) => ({
label: n.label,
value: n.value,
children: n.children && n.children.length > 0 ? convert(n.children) : undefined,
}));
}
return tree.value ? convert(tree.value) : [];
});
const selected = ref('');
</script>
URadioGroup / UCheckbox
<template>
<div class="flex flex-col gap-2">
<URadioGroup v-model="radio" :items="options" :loading="loading" />
<UCheckbox
v-for="opt in options"
:key="opt.value"
v-model="checkbox"
:value="opt.value"
:label="opt.label"
/>
</div>
</template>
<script setup lang="ts">
const { options, loading } = useDict('gender');
const radio = ref('');
const checkbox = ref<string[]>([]);
</script>
UBadge 状态标签
<template>
<div class="flex gap-2">
<UBadge
v-for="opt in options"
:key="opt.value"
:label="opt.label"
:color="getBadgeColor(opt.value) as any"
variant="subtle"
/>
</div>
</template>
<script setup lang="ts">
const { data, options } = useDict('status');
function getBadgeColor(value: string | number) {
return (data.value?.find((i) => i.value === code) as any)?.color ?? 'neutral';
}
</script>
UForm 表单(多字典组合)
<template>
<UForm :state="form" class="space-y-4">
<UFormGroup label="性别" name="gender">
<USelect v-model="form.gender" :items="gOpts" :loading="gLoading" />
</UFormGroup>
<UFormGroup label="行业" name="industry">
<USelect v-model="form.industry" :items="iOpts" :loading="iLoading" />
</UFormGroup>
<UFormGroup label="状态" name="status">
<USelectMenu v-model="form.status" :items="sOpts" :loading="sLoading" />
</UFormGroup>
</UForm>
</template>
<script setup lang="ts">
const { options: gOpts, loading: gLoading } = useDict('gender');
const { options: iOpts, loading: iLoading } = useDict('industry');
const { options: sOpts, loading: sLoading } = useDict('status');
const form = reactive({ gender: '', industry: '', status: '' });
</script>