背景
在开发过程中,前端会和后端约定好枚举,前端在某些场景下需要维护枚举。如何维护好枚举是个头痛的问题。
问题
我这边拿性别枚举举例:
// 约定好0是男性,1是女性
const SEX_ENUM: {
MALE: 0
FEMALE: 1
}
如果这个枚举牵扯的信息比较多,前端得维护一套描述的性别数组:
const sexList = [
{ value: SEX_ENUM.MALE, label: '男', avatarUrl: 'https://xxx/male' },
{ value: SEX_ENUM.FEMALE, label: '女', avatarUrl: 'https://xxx/female' },
]
然后我们渲染信息,展示性别的头像、文本。这边拿vue举例:
头像: <img :src="sexList.find(item => item.value === sex).avatarUrl" />
性别: <span>{{ sexList.find(item => item.value === sex).label }}</span>
此时,我们能发现一个问题。如果我们想要获取某个枚举值对应的信息,需要通过find函数找到枚举对应的配置对象才能拿到信息。这里只是维护了头像和性别,如果更多需要再次重复写这段逻辑。
然后再新增几个个未知的性别,还有几个个性别对应的文案或者是颜色。此时你需要维护SEX_ENUM和sexList两组配置,这又产生一个维护麻烦的新的问题。
解决
为了解决上述问题,我写了一个库。这个库很简单,下面是源码和使用方式:
function enumify(items) {
const obj = (value) => {
return items.find((item) => item.value === value);
};
items.forEach((item) => {
obj[item.key] = item.value;
});
return obj;
}
enumify函数会将提供的配置,转换成一个枚举对象。同时枚举对象也是一个函数,通过接收枚举值返回对应的配置对象。
接下来使用这个函数:
const SEX_ENUM = enumify(/** @type {const} */([
{ key: 'MALE', value: 0, meta: { label: '男', avatarUrl: 'https://xxx/male' } },
{ key: 'FEMALE', value: 1, meta: { label: '女', avatarUrl: 'https://xxx/female' } },
]))
然后进行渲染:
头像: <img :src="SEX_ENUM(sex).meta.avatarUrl" />
性别: <span>{{ SEX_ENUM(sex).meta.label }}</span>
此时上述的一些问题也得到了解决。不需要重复写find方法了,我们也不需要维护两个配置了,现在只需要维护enumify里的配置就行了。
补充
有可能有些细心的小伙伴发现了/** @type {const} */的注释,没错,这个库是typescript 写的,支持代码提示。
如果大家对如何实现提示感兴趣话可以访问我的代码仓库查看源码。可以的话顺手给个star,感谢!