Javascript 枚举工具封装
先来看看使用:
// 控件中绑定
<div>
<!-- 以 ant-design-vue 为例 -->
<!-- 绑定下拉列表数据 -->
<a-select :options="StatusEnum._list"></a-select>
<!-- 按不同样式展示中文 -->
<div :class="StatusEnum._classOf(detail.status)">
{{ StatusEnum._of(detail.status) }}
</div>
<!-- 判断 -->
<div v-if="detail.status === StatusEnum.eFrozen">
...
</div>
</div>
// js中使用
import StatusEnum from '../enum/StatusEnum.js'
// 这是后端返回的详情对象,比如状态status,后端一般只返回编码,展示时需要转成中文
const detail = {
id: 1,
name: 'xxx',
status: 1
}
// 前端展示时转成中文
StatusEnum._of(detail.status) // 结果为:未冻结
// 判断状态是否为已冻结
if (detail.status === StatusEnum.eFrozen) {
// xxx
}
// 获取所有枚举对象,用于绑定到下拉列表等组件上
const list = StatusEnum._list
// 获取枚举对象
const enumObj = StatusEnum._objectOf(detail.status)
// 其他自定义方法
const canEdit = StatusEnum._canEdit(detail.status)
枚举对象 StatusEnum.js 代码如下:
import { Enum, init } from '@/utils/enum.util.js'
/**
* 冻结状态
*/
const StatusEnum = {
eUnfrozen: Enum(1, '未冻结', 'is-primary'), // 第三个参数为字符串时代表class样式,为boolean时代表disabled是否禁用,为object时代表data自定义扩展对象
eFrozen: Enum(2, '已冻结', 'is-warning'),
eThawed: Enum(3, '已解冻', 'is-success'),
// 以下代码只是为了代码提示,可删除,会在init中重新定义
_of (id) {},
_classOf (id) {},
_objectOf (id) {},
_list: [],
// 其他自定义方法,统一使用”_“开头(方便代码提示,个人习惯,非强制)
_canEdit (id) {
return [this.eUnfrozen, this.eThawed].includes(id)
}
}
init(StatusEnum)
export default StatusEnum
工具类 enum.util.js 代码如下:
/**
* 枚举对象
* extra 为 boolean 时代表 disabled
* extra 为 string 时代表 class
* extra 为 object 时代表 data,此时第四个参数 data 无效
* data 代表扩展属性
* {id, name, disabled} or {id, name, class} or {id, name, data} or {id, name, disabled, data} or {id, name, class, data}
*/
export const Enum = (id, name, extra, data = {}) => {
const disabled = typeof extra === 'boolean' ? extra : (data.disabled || false)
const _class = typeof extra === 'string' ? extra : data.class
const _data = typeof extra === 'object' ? extra : data
return {
id,
name,
disabled,
class: _class,
data: _data,
key: id,
value: id,
label: name,
title: name,
text: name,
isEnum: true,
toString () {
return this.id
}
}
}
/**
* 初始化
*/
export function init (enumObj) {
const keys = Object.keys(enumObj).filter((key) => enumObj[key].isEnum)
enumObj._list = keys.map((key) => ({ ...enumObj[key] }))
// 为了简化大部分使用情况,用ID覆盖原本的对象,要获取对象请用 _objectOf 方法
for (let i in keys) {
enumObj[keys[i]] = enumObj[keys[i]].id
}
enumObj._of = (id, default = '-') => {
return enumObj._objectOf(id).name ?? default
}
enumObj._objectOf = (id, useDefault = true) => {
let result = enumObj._list.find((item) => item.id === id || String(item.id) === String(id))
return useDefault ? (result || Enum()) : result
}
enumObj._classOf = (id) => {
return enumObj._objectOf(id).class
}
if (Object.freeze) {
Object.freeze(enumObj)
}
}