背景
前端开发的时候总是会用到枚举值,对于枚举值我们的应用场景如下:
- 页面下拉框的枚举类型以及枚举类型对应的数字量
- 后台返回数字量,前端需要显示对应的文本描述
以前我们的做法是分开放在不同的地方的,其实我还是想将数据来源放在统一的地方进行管理,然后根据数据源进行一个变体,一个支持枚举变量,一个支持数字量对应返回的文本描述
js版本
函数加载通过数据源 + 枚举注入 =》 生成对应的对象,想用到的方法通过方法直接获取就好。
index.js 枚举入口文件
commonEnum文件夹下的index,主要是工具函数,在业务文件调用时,返回对应的枚举对象。
/* eslint-disable camelcase */
import _ from "lodash";
import sourceData from "./sourceData";
const highForatFunction = enumSourceData => {
// 根据数据源处理返回枚举类型
const enumValue = {};
_.forEach(enumSourceData, item => {
enumValue[item.key] = item.value;
});
// 枚举数据源,根据value值获取lable文本值
const getLabelByValue = value => {
const filterObject = _.filter(enumSourceData, item => item.value === value);
// 存在返回值,返回第一个匹配的数据
if (filterObject.length) {
return filterObject[0].label;
}
// 没有返回值的情况下,返回空
return "";
};
return {
enum: enumValue,
getLabelByValue
};
};
const injectEnumFunction = sourceDataKeyArray => {
// 数据类型检查
if (!_.isArray(sourceDataKeyArray)) {
throw new Error("注入失败,参数格式不正确");
}
const injectEnumOject = {};
_.forEach(sourceDataKeyArray, item => {
// eslint-disable-next-line no-prototype-builtins
if (sourceData.hasOwnProperty(item)) {
injectEnumOject[item] = highForatFunction(sourceData[item]);
} else {
throw new Error(`注入失败,没有${item}对应的枚举数据`);
}
});
return injectEnumOject;
};
export default injectEnumFunction;
复制代码
sourceData.js 数据源文件
数据源文件:枚举主题内部的每一个单体对象,内部的三个属性值:key,value,label。
const sourceData = {
userAccountTypeEnum: [
{
key: "STAFF",
value: 1,
label: "员工"
},
{
key: "COMPANY",
value: 2,
label: "公司"
}
]
};
export default sourceData;
复制代码
使用方式
引入injectEnumFunction
import injectEnumFunction from "@/common/commonEnum";
复制代码
调用方式,注入userAccountTypeEnum枚举类型值
const { userAccountTypeEnum } = injectEnumFunction(["userAccountTypeEnum"]);
复制代码
得到的结果是:
返回的结果是两个属性,一个是enum枚举值。另一个是一个function,用于通过key值获取对应的文本信息。
dumi & ts版本
创建项目
yarn create @umijs/dumi-lib --site
复制代码
代码结构
核心代码
import _ from 'lodash';
import {
EnumItem,
EnumBase,
TypeEnum,
InjectEnumObject,
SourceData,
} from './type';
class EnumStoreClass {
private _sourceData: SourceData = {};
private _highForatFunction = (enumSourceData: EnumItem[]) => {
// 根据数据源处理返回枚举类型
const enumValue: EnumBase = {};
_.forEach(enumSourceData, (item) => {
enumValue[item.key] = item.value;
});
// 枚举数据源,根据value值获取lable文本值
const getLabelByValue = (value: TypeEnum) => {
const filterObject = _.filter(
enumSourceData,
(item) => item.value === value,
);
// 存在返回值,返回第一个匹配的数据
if (filterObject.length) {
return filterObject[0].label;
}
// 没有返回值的情况下,返回空
return '';
};
return {
enum: enumValue,
getLabelByValue,
};
};
public initData(initData: SourceData) {
this._sourceData = initData;
}
public injectEnumFunction = (sourceDataKeyArray: string[]) => {
// 数据类型检查
if (!_.isArray(sourceDataKeyArray)) {
throw new Error('注入失败,参数格式不正确');
}
const injectEnumOject: InjectEnumObject = {};
_.forEach(sourceDataKeyArray, (item) => {
// eslint-disable-next-line no-prototype-builtins
if (this._sourceData.hasOwnProperty(item)) {
injectEnumOject[item] = this._highForatFunction(this._sourceData[item]);
} else {
throw new Error(`注入失败,没有${item}对应的枚举数据`);
}
});
return injectEnumOject;
};
}
const enumStore = new EnumStoreClass();
export const initEnumSourceData = (initData: SourceData) => {
enumStore.initData(initData);
};
export const injectEnumFunction = (sourceDataKeyArray: string[]) => {
return enumStore.injectEnumFunction(sourceDataKeyArray);
};
export * from './type';
复制代码
export type TypeEnum = number | string;
export interface EnumItem {
key: TypeEnum;
label: TypeEnum;
value: TypeEnum;
}
export interface EnumBase {
[key: number]: TypeEnum;
[key: string]: TypeEnum;
}
export interface InjectEnumItem {
enum?: EnumBase;
getLabelByValue?: Function;
}
export interface InjectEnumObject {
[key: string]: InjectEnumItem;
}
export interface SourceData {
[key: string]: EnumItem[];
}
复制代码
使用
import React from 'react';
import { injectEnumFunction, initEnumSourceData, SourceData } from 'rofo-enum';
const sourceData: SourceData = {
userAccountTypeEnum: [
{
key: 'STAFF',
value: 1,
label: '员工',
},
{
key: 'COMPANY',
value: 2,
label: '公司',
},
],
};
for (let i = 0; i < 10000; i++) {
sourceData['userAccountTypeEnum' + i] = [
{
key: 'STAFF',
value: 1,
label: '员工',
},
{
key: 'COMPANY',
value: 2,
label: '公司',
},
];
}
initEnumSourceData(sourceData);
console.time('test-start');
const { userAccountTypeEnum9999 } = injectEnumFunction([
'userAccountTypeEnum9999',
]);
console.log(userAccountTypeEnum9999.enum);
console.log(userAccountTypeEnum9999.getLabelByValue(1));
console.timeEnd('test-start');
复制代码
性能测试
这里用了console.time进行性能测试。因为是属性访问,所以性能没什么影响。
本地如何调试
当我们还没有将代码发布到npm当中的时候,可以本地如下设置:
然后示例中就可以直接像下面这种代码使用进行测试:
import { injectEnumFunction, initEnumSourceData, SourceData } from 'rofo-enum';
复制代码
发布在线npm包
当我们写好代码,写好在线文档,提交代码,然后发布版本。
npm run release
复制代码
然后到npm网站就可以看到发布的包【这里的readme没有修改好,不耽误使用】
发布在线文档
npm run deploy
复制代码
然后到对应的github项目地址当中可以看到gh-pages分支
点击查看:页面是空白,主要原因是这里的路径访问是有二级域名的,所以需要重新修改一下代码。
这里是为了适配github部署网站
然后我们就可以看到我们部署的网站
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END