优雅使用前端枚举Enum,符合国标的那种!

01、什么是枚举Enum?
枚举Enum是在多种语言中都有的一种数据类型,用于表示一组特定相关的常量数据集合,如性别(男、女)、数据状态(可用、禁用)、垂直对齐(顶端、居中、底部)、星期等。特点是数据值固定,不会变,存储和显示的内容不同。
然而在JavaScript中并没有枚举Enum类型,TypeScript算是有(本文中暂没用用TS的枚举)。在前端项目中还是会用到经常用到这类型数据的,本文就对枚举做一个通用封装,并进行尽量全局的总结。
先来看看最常用的性别:
| Text文字(界面显示) | 编码(编码、传输、存储使用) | 数字值(存储使用) |
|---|---|---|
| 男 | male/man/M | 1 |
| 女 | female/woman/F | 2 |
| 其他 | other | 3 |
你的系统中性别用的什么存储的呢?
- 在UI上显示为
Text文字描述,如表格、单选项。 - 传输或存储时,一般会用一个有意义的字符编码,或者数字,两种方式都有也都可以。
- 如果数据量少,可以用字符编码,如M(男)、Male(男),可读性更好,就是占用空间比数字类型多。
- 推荐采用短整形数字表示,存储空间更小,采用一个字节的最小整形即可(值为0到255)。

针对性别的枚举值,其实是有国家标准的,国标中就是用的整数值标识。
参考国标:GB/T 2261.1-2003 个人基本信息分类与代码 第1部分:人的性别代码(可在线预览),早在2003年就颁布了。

SO,我们用枚举的主要目的就是处理UI、存储(编码传输)的值转换问题,兼顾显示的友好、存储的性能。在一些面向对象语言如JAVA、C#中使用体验更佳,支持枚举值的代码提示输入,避免硬编码,还可以用位运算存储多个值(算是稍微高级一点的玩法了)。
02、前端应用场景

1、表格数据绑定时,需要显示用户易懂的(中文)描述信息,用不同颜色样式区分,而后端返回的JSON数据中可能是编码值M/F,或1/2。

2、直接显示枚举值的(中文)描述信息+样式,如elementUI中的<el-tag>组件。

3、作为表单组件的绑定数据源,如下拉选择、单选组、复选组表单组件。

03、封装EnumFactory
3.1、EnumFactory
设计一个枚举工厂 EnumFactory(enumFactory.js),统一创建枚举所需的属性和方法:
- 参数
enumObj为要传入的枚举基础定义:- 标准模式(
key:{text:'',type:''})示例:{ 1: { text: '男', type: 'priary' }, 2: { text: '女', type: 'warning' }} - 简写模式(
key:text),会被自动转换为标准模式,示例:{ left: '左对齐', center: '居中', right: '右对齐' } - **value **数据结构约定:
value值部分约定text为文本描述,type为样式类别(elementUI中的状态type:success/info/warning/danger),其他可随意。
- 标准模式(
- 参数
keyParseFunc为key的转换函数,默认key为字符串,keyParseFunc默认值为null(不转换),如果key为整数,则需要传入转换函数(传入JS内置parseInt即可)。 - 返回值继承自参数
enumObj,扩展了属性 keys、values、formatter。**keys**,枚举key数组,如[0,1,2]、["male","female","other"]。**values**,值数组,包含了key,结构[{key:'',text:'',type:''}]。**formatter**:elementUI中表格绑定枚举数据文本的formatter函数。
/**
* 枚举创建工厂(构造函数),扩展枚举对象:keys、values(含key值的[{key,text,type}])、formatter。
* @param {*} enumObj 枚举值,支持标准模式{key:{text,type},},简单模式{key:text,}(会自动转换为标准模式)
* @param {*} keyParseFunc key的转换函数,默认null,如果key为整数则传 parseInt
*/
export default function EnumFactory(enumObj, keyParseFunc = null) {
//复制(继承)enumObj
Object.assign(this, enumObj)
// keys:枚举的key集合[key]
Object.defineProperty(this, 'keys', {
value: keyParseFunc ? Object.keys(enumObj).map(s => keyParseFunc(s)) : Object.keys(enumObj)
})
// 处理 values
let values = []
const ovalues = Object.values(enumObj)
// 主要区分下value是简单类型(字符串)还是对象类型
if (typeof ovalues[0] === 'string') {
ovalues.forEach((text, index) => {
const obj = { key: this.keys[index], text }
values.push(obj)
this[this.keys[index]] = obj
})
}
else {
ovalues.forEach((item, index) => {
item.key = this.keys[index]
values.push(item)
})
}
// 设置values属性
Object.defineProperty(this, 'values', { value: values })
// formatter:element中表格绑定枚举数据文本的formatter函数
// r、c为行列,可传入null
Object.defineProperty(this, 'formatter', {
value: function(r, c, value) {
return values.filter(v => v.key == value || v.text == value)[0]?.text || 'notfound'
}
})
//枚举定义的数据都是常量,不可修改,冻结一下
Object.freeze(this)
}
3.2、基于EnumFactory定义枚举值
创建一个enums.js存放常用枚举常量:
- 性别枚举对象(key为整数)
- 使用状态
- 对齐方式
import EnumFactory from "@/utils/enumFactory";
/**
* 性别枚举对象(key为整数)
*/
export const enumGender = new EnumFactory({
1: { text: '男', type: 'priary' },
2: { text: '女', type: 'warning' },
9: { text: '其他', type: 'info' },
},parseInt)
/**
* 使用状态
*/
export const enumUse = new EnumFactory({
enable: { text: '启用', type: 'success' },
disable: { text: '禁用', type: 'danger' }
})
// 对齐方式
const enumAlign = new EnumFactory({ left: '左', middle: '中', right: '右' })
enumGender的结构如下:

enumGender.keys:[0,1,2]enumGender.values:[{"text":"其他","type":"info","key":0},{"text":"男","type":"priary","key":1},{"text":"女","type":"warning","key":2}]
04、ElementUI中使用
1、表格数据绑定时,显示用户易懂的(中文)描述信息,用不同颜色样式区分。使用自template模板自定义,或者formatter函数,格式化函数就不支持样式状态了。
关键代码:enumGender[scope.row.gender]?.text
<el-table :data="table">
<el-table-column label="姓名" prop="name" width="220px"></el-table-column>
<el-table-column label="性别" prop="gender" align="center" width="120px">
<template slot-scope="scope">
<el-tag :type="enumGender[scope.row.gender]?.type">{{ enumGender[scope.row.gender]?.text }}</el-tag>
</template>
</el-table-column>
<el-table-column label="方向" prop="align" :formatter="enumAlign.formatter" width="120px"></el-table-column>
<el-table-column label="状态" prop="use" align="center" width="120px">
<template slot-scope="scope">
<el-tag :type="enumUse[scope.row.use]?.type">{{ enumUse[scope.row.use]?.text }}</el-tag>
</template>
</el-table-column>
</el-table>
效果:

2、直接显示枚举值的(中文)描述信息+样式,用type来绑定状态样式。
<el-form-item label="状态标签-all">
<el-tag v-for="tag in enumGender.values" :key="tag.key" :type="tag.type" style="margin-right: 10px;">
{{tag.text }}
</el-tag>
</el-form-item>
<el-form-item label="状态标签-值">
<el-tag :type="enumGender[value]?.type">{{ enumGender[value]?.text }} : {{ value }}</el-tag>
</el-form-item>
效果:

3、作为表单组件的绑定数据源,如下拉选择、单选组、复选组表单组件。
用enumAlign.values作为源来绑定
<el-form-item label="下拉选择">
<el-select v-model="value">
<el-option v-for="e in enumAlign.values" :key="e.key" :value="e.key" :label="e.text"></el-option>
</el-select>
</el-form-item>
<el-form-item label="单选组1">
<el-radio-group v-model="value">
<el-radio-button v-for="item in enumAlign.values" :key="item.key" :label="item.key">{{ item.text }}</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="单选组2">
<el-radio-group v-model="value">
<el-radio v-for="item in enumAlign.values" :key="item.key" :label="item.key">{{ item.text }}</el-radio>
</el-radio-group>
</el-form-item>
效果:

总结
其实本质上就是设计一个标准的数据结构,能够方便的获取所有枚举数据项,然后根据值快速获取显示的文本。
参考资料
- 性别国标:GB/T 2261.1-2003 个人基本信息分类与代码 第1部分:人的性别代码
- 开源项目库:kvue-admin
- 文中使用示例源码:enums.vue
️版权申明:版权所有@安木夕(kanding),本文内容仅供学习,欢迎指正、交流,转载请注明出处!
原文编辑地址:https://www.yuque.com/kanding
优雅使用前端枚举Enum,符合国标的那种!的更多相关文章
- 前端枚举enum的应用(Element)封装
什么是枚举Enum 枚举 Enum是在众多语言中都有的一种数据类型,JavaScript中还没有(TypeScript有).用来表示一些特定类别的常量数据,如性别.学历.方向.账户状态等,项目开发中是 ...
- java枚举(enum)
1. 创建枚举类型要使用 enum 关键字,隐含了所创建的类型都是 java.lang.Enum (抽象类) 类的子类. enum AccountType { SAVING, FIXED, CURRE ...
- 如何在MyBatis中优雅的使用枚举
问题 在编码过程中,经常会遇到用某个数值来表示某种状态.类型或者阶段的情况,比如有这样一个枚举: public enum ComputerState { OPEN(10), //开启 CLOSE( ...
- java枚举enum equal与==
原文链接:https://www.cnblogs.com/xiohao/p/7405423.html 问题 我知道Java枚举会被编译成一个包含私有构造参数和一堆静态方法的类,当去比较两个枚举的时候, ...
- MySQL字段之集合(set)枚举(enum)
MySQL字段之集合(set)枚举(enum) (2008-12-23 13:51:23) 标签:it 分类:MySQL 集合 SET mysql> create table jihe(f1 ...
- 枚举 enum
typedef enum : NSUInteger { <#MyEnumValueA#>, <#MyEnumValueB#>, <#MyEnumValueC#>, ...
- 枚举enum学习小记
参考文献: [1]C++程序设计语言(特别版), 裘宗燕译, 机械工业出版社 [2]C++ Primer (3rd Ed.), S.B. Lippman and J. Lajoie, 人民邮电出版社 ...
- Java 枚举(enum) 详解7种常见的用法
Java 枚举(enum) 详解7种常见的用法 来源 https://blog.csdn.net/qq_27093465/article/details/52180865 JDK1.5引入了新的类型— ...
- Python 枚举 enum
Python 枚举 enum enum 标准模块在 3.4 版本才可以使用,3.3 以下版本需要独立安装:https://pypi.python.org/pypi/enum34#downloads,官 ...
- 【转】结构struct 联合Union和枚举Enum的细节讨论
结构struct 联合Union和枚举Enum的细节讨论 联合(Union)是一种构造数据类型,它提供了一种使不同类型数据类型成员之间共享存储空间的方法,同时可以实现不同类型数据成员之间的自动类型转换 ...
随机推荐
- [转帖]如何在 Linux 中使用ss命令监控网络连接
https://zhuanlan.zhihu.com/p/99421574 ss命令是用于在Linux系统上显示与网络套接字相关的信息的工具. 该工具显示netstat命令的更多详细信息,该命令用于显 ...
- [转帖]5、kafka监控工具Kafka-Eagle介绍及使用
https://zhuanlan.zhihu.com/p/628039102 # Apache Kafka系列文章 1.kafka(2.12-3.0.0)介绍.部署及验证.基准测试 2.java调 ...
- [转帖]拜托!面试请不要再问我Spring Cloud底层原理
https://www.cnblogs.com/jajian/p/9973555.html 概述# 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术.不过大 ...
- .NET Core(C#) PadLeft和PadRight特定格式字符串长度补齐的方法和js中如何填充字符串
.NET Core(C#) 1、PadLeft和PadRight使用说明 两个方法都是对字符串格式化进行补齐填充,PadLeft是左边,而PadRight是右边 '1010'.PadLeft(10,' ...
- 在bat中切换盘符
在bat代码中如何在不同的盘符中切换?直接输入盘符的名字,前面不要加cd,示例 cd %~dp0 d: cd D:\Python37 e: cd E:\Code\KSFramework c: cd C ...
- word 常用设置
目录 目录 关闭 Word 句首字母自动大写功能 1 Word 生成目录 1 Word 快速调整标题级别 1 Word 关闭句首字母自动大写功能 参考:https://zhuanlan.zhihu.c ...
- MySQL8.0清空binlog
环境 centos7.9 mysql Ver 8.0.32 登录MySQL,查看binlog日志 #查看binlog日志开启状态,log_bin值为ON表示开启状态 mysql> show v ...
- JWT( JSON Web Token —— JSON Web 令牌 )的学习笔记
一.跨域认证的问题 互联网服务离不开用户认证.一般流程是下面这样: 1.用户向服务器发送用户名和密码. 2.服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色.登录时间等等. ...
- tp使用workerman消息推送
安装 首先通过 composer 安装 composer require topthink/think-worker SocketServer 在命令行启动服务端 php think worker:s ...
- electron 开发 ,如何使用 第三方 库 进行typescript 开发,举例:jquery 其它的 应该也是一致。
首先要弄明白一点,electron 开发 与 nodejs开发 基本一致. 要引入 jquery 实际上就是 nodejs 引入 jquery 第一步是 去 nmp中央仓库,查看,里面有详细的说明使用 ...