useDict

useDict 完整用法详解 —— 获取字典数据并翻译。

本章目标:掌握 useDict 的所有用法,包括基础翻译、loading/error 处理、手动刷新和指定存储库。

什么时候需要这个功能?

  • 你有一个表格,其中"状态"列存的是 0 / 1,但你希望用户看到"启用" / "禁用"
  • 你需要同时拿到字典原始数据和翻译能力
  • 你需要自己控制字典数据的渲染方式

完整签名

// 使用默认存储库
useDict(type: string): UseDictReturn

// 指定存储库
useDict(storeName: string, type: string): UseDictReturn

返回值

属性类型说明
dataShallowRef<DictItem[] | null>字典原始数据数组。初始为 null,加载完成后变成 [{ value: 0, label: '禁用' }, ...]
translate(value: string | number) => string同步翻译函数。输入 code,输出对应的 label。如果 code 不存在,返回 code 本身的字符串形式
getDictItem(value: string | number) => DictItem | undefined同步获取完整字典项对象。输入 code,返回 { value, label, ... },未命中返回 undefined
loadingRef<boolean>是否正在加载
errorRef<string | null>加载失败时的错误信息
refresh() => Promise<void>手动刷新,强制跳过缓存

基础示例

<template>
  <div>
    <p v-if="loading">加载中...</p>

    <div v-else-if="error" style="background:#fef0f0;padding:16px;border-radius:8px;">
      <p style="color:#F56C6C;">{{ error }}</p>
      <button @click="doRefresh">重试</button>
    </div>

    <table v-else border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;">
      <thead>
        <tr>
          <th>编码 (code)</th>
          <th>显示文字 (label)</th>
          <th>翻译验证</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in data" :key="item.value">
          <td>{{ item.value }}</td>
          <td>{{ item.label }}</td>
          <td>{{ translate(item.value) }}</td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script setup lang="ts">
const { data, translate, loading, error, refresh } = useDict('status');

function doRefresh() {
  refresh();
}
</script>

翻译函数详解

translate(value) 是同步函数,它只查找当前已加载到内存缓存中的数据,不需要等网络请求:

<template>
  <table>
    <tr v-for="user in userList" :key="user.id">
      <td>{{ user.name }}</td>
      <!-- user.status 是数字 0/1/2 → 翻译成"禁用"/"启用"/"待审核" -->
      <td>{{ translate(user.status) }}</td>
    </tr>
  </table>
</template>

为什么翻译是同步的?useDict('status') 在组件挂载时已经完成了数据加载,status 的字典数据就存放在内存缓存中了。之后调用 translate(statusCode) 直接从内存中查找。

获取完整字典项 (getDictItem)

当需要获取字典项的完整对象(而非仅某个字段的翻译)时使用。比如拿到 color 字段给组件属性用。

<template>
  <el-tag :color="statusItem?.color as string" effect="dark">
    {{ statusItem?.label }}
  </el-tag>
</template>

<script setup lang="ts">
const { getDictItem } = useDict('status');

const statusItem = computed(() => getDictItem(1));
// → { value: 1, label: '启用', color: '#67C23A' }
</script>

getDictItem 也是同步的,从内存缓存查找。缓存未命中时返回 undefined

code 类型自动转换

字典项的 code 可能是 number(如 0),而你的业务数据可能是 string(如 '0')。translate() 内部自动把两边都转成字符串比较:

translate(0); // → '禁用'
translate('0'); // → '禁用'

手动刷新

当你知道后端字典数据已经更新时,可以调用 refresh() 强制重新拉取:

<script setup lang="ts">
const { data, refresh } = useDict('status');

function onDictUpdated() {
  refresh(); // 后端通知字典有更新 → 清除缓存并重新请求
}
</script>

refresh() 的行为:清除内存缓存 → 跳过 IndexedDB → 直接向服务器发起新请求 → 写入 IndexedDB + 内存。

指定存储库

<script setup lang="ts">
// 默认存储库 'dicts'
const { data } = useDict('gender');

// 指定存储库 'payment'
const { data: payData } = useDict('payment', 'status');
</script>

多仓库的详细配置见 多仓库 章节。

作用域与响应式行为

useDict组件级 composable,每个调用组件持有独立的 shallowRef。组件挂载(onMounted)时自动请求字典数据,数据到达后模板自动重渲染。语言切换时监听 manager.locale 变化自动重新加载。

  • 响应式:是。dataShallowRef,Vue 追踪其引用变化,模板自动更新
  • 调用位置:必须在 <script setup> 顶层调用,不能在回调 / 条件分支 / 普通函数中调用
  • 适合场景:模板绑定(select 选项、列表渲染、树形展示)

$dict全局级同步翻译器,不产生 Vue 响应式依赖。详见 $dict 同步翻译

注意事项

translate()datanull 时仍可调用,但会返回 code 原文。确保在 v-if="data" 或用 loading 状态包裹。

本章你学会了

  • 使用 useDict('type') 获取字典数据和翻译函数
  • 正确处理 loading / error 三种状态
  • translate() 做 code → label 转换
  • getDictItem() 获取完整字典项对象(含扩展字段)
  • 调用 refresh() 强制刷新缓存
  • 使用 useDict('store', 'type') 指定存储库