在使用Vue
开发中经常碰到一些字典转换
的问题,如根据字典数据开发的一些选择框,table中根据字段值展示字典的lable等。每次都手写这些选择项或者转换字典值很是麻烦,并且字典改变之后还要修改对应的代码很是不便,所以就想着封装一个字典工具来解决这个问题。
思路
第一步:使用Vuex
管理字典数据。
第一步:创建一个DictUtil
提供两个方法dictDataUtil
和dictDataLableUtil
。
dictDataUtil
: 根据字段类型从Vuex
中获取该字典的所有字段项数据dictDataLableUtil
: 根据字段类型从Vuex
中获取该字典的该字段值对应的lable
第三步:将上面的方法封装成一个插件,安装在项目中,方便在项目中调用。
实现代码
使用Vuex获取存储字典数据
- 创建
DictStore.ts
文件,在DictStore
文件中使用Vuex
管理字典数据
import { getDictItemsApi } from "@/api/dict";
import { Module } from "vuex";
export interface IDictItem {
id: string;
lable: string;
value: string | number | boolean;
}
// 存储字典数据
export const dicts = new Map<string, IDictItem[]>();
interface IDict {
[key: string]: Map<string, IDictItem[]>;
}
const DictStoreModule: Module<IDict, any> = {
state: { dicts },
getters: {
getDict:
(state) =>
(key: string): IDictItem[] | undefined => {
const dict = state.dicts.get(key);
return dict;
},
},
mutations: {
setDict(state, payload: Map<string, IDictItem[]>): void {
payload.forEach((v, k) => {
state.dicts.set(k, v);
});
},
delDict(state, payload: string): boolean {
return state.dicts.delete(payload);
},
clearAll(state: IDict): void {
return state.dicts.clear();
},
},
actions: {
fetchDict: async (context, payload: string): Promise<void> => {
const dict = new Map<string, IDictItem[]>();
dict.set(payload, []);
context.commit("setDict", dict);
const data = await getDictItemsApi(payload);
dict.set(payload, data);
context.commit("setDict", dict);
},
},
};
export default DictStoreModule;
创建一个字典工具DictUtil
,提供dictDataUtil
和dictDataLableUtil
方法。
import { IDictItem } from "@/store/modules/DictStore";
import { useStore } from "vuex";
export const dictDataUtil = (dictType: string): IDictItem[] | null => {
const store = useStore();
const dictData = store.getters.getDict(dictType);
if (!dictData) {
store.dispatch("fetchDict", dictType);
}
return dictData;
};
export const dictDataLableUtil = (
dictType: string,
dictValue: string | number | boolean
): string | null => {
const store = useStore();
const dictData = store.getters.getDict(dictType);
if (!dictData) {
store.dispatch("fetchDict", dictType);
}
if (dictData) {
const dictItem = dictData.find((d: IDictItem) => d.value === dictValue);
if (dictItem) {
return dictItem.label;
}
}
return null;
};
创建字段插件
将dictDataUtil
和dictDataLableUtil
方法封装成一个字典插件,以便全局安装
import { App } from "vue";
import { dictDataUtil, dictDataLableUtil } from "@/utils/DictUtil";
const DictInstall = {
install: (app: App): App<any> => {
app.mixin({
methods: {
dictData: dictDataUtil,
dictDataLable: dictDataLableUtil,
},
});
return app;
},
};
export default DictInstall;
安装这个插件
安装字典插件,以方便在项目使用
import DictInstall from "./plugins/DictPlugin";
const app = createApp(App);
app.use(DictInstall).mount("#app");
使用方式
安装插件之后在项目中可以直接使用{{dictData}}
、{{dictDataLable}}
的方式转换字典,如:
效果:
在table
中可以使用{{dictDataLable}}
将字典值转成字段lable
存在的问题
在form
表单中使用还存在问题,既不能使用{{dictData()}}
的方式提供选择框的选项。一种不太优雅的变通方式是使用computed
和dictDataUtil
方法完成的,见下:
欢迎有解决方法的大佬评论留言。