Skip to content

字典

字典这块在开始写的时候参考了其他框架, 大致是有两种方式

方式优点缺点
直接加载全部字典使用方便, 直接从字典 store 取值会造成浪费且后端不支持
按需加载, 使用前需要显式导入后端支持, 懒加载每次使用前都得显式声明

都不符合需求 且使用 VbenForm 像 Select 这种组件是不支持Promise 形式 返回对应字典的(可支持, 但操作复杂)

使用

底层已经封装好了逻辑, 直接使用即可apps/web-antd/src/utils/dict.ts

ts
import { getDictOptions } from "#/utils/dict";

/**
 * getDict方法已经废弃 统一使用getDictOptions代替
 */

渲染标签(tag)使用

ts
import { renderDict } from "#/utils/render";

...
slots: {
  default: ({ row }) => {
    return renderDict(row.configType, DictEnum.SYS_YES_NO);
  },
},
...

getDictOptions为一些 Select 组件使用 比如 select radio checkbox 等, 统一需要这样的结构

ts
/**
 * antd使用 select和radio通用
 */
export interface Option {
  disabled?: boolean;
  label: string;
  value: string;
}

所以单独提出来, 方便使用

ts
{
  component: 'Select',
  componentProps: {
    getPopupContainer,
    options: getDictOptions(DictEnum.SYS_YES_NO),
  },
  fieldName: 'configType',
  label: '系统内置',
},

注意 Version>=1.2.0

我的业务对象为 Int/Long 等, 与字典的 String 类型对不上导致无法选中 怎么解决

使用第二个参数 将字典 value 转为 number 如getDictOptions(DictEnum.SYS_YES_NO, true)

注意不允许在 代码A 处使用 String 代码B 处使用 Number 的用法!!! 会存在问题(能写出这种应该是你的问题 😅)

与之提到的方案相比, 即不会全部加载也不用手动先声明才能使用

注: 以上提到的手动声明类似于这种

ts
const dict = ref();
onMounted(async () => {
  dict.value = await dictApi("dict_name");
});

// 然后使用dict

需要在业务逻辑中使用字典的情况

以上只是针对渲染标签/组件options使用的情况, 如果需要在业务逻辑中使用字典, 直接调用字典 api 接口

注意

getDict, getDictOptions 非 Promise 方法 但是内部是采用 Promise 封装的, 直接在业务逻辑中使用会拿到空数据

ts
function test() {
  const xxx = getDict("dict_name");
  // 这里为空数组
  xxx;
}

正确做法

ts
// 使用api来获取
import { dictDataInfo } from "#/api/system/dict-data";

async function test() {
  const xxx = await dictDataInfo("dict_name");
  // 这里是字典数据
  xxx;
}