优雅使用前端枚举Enum,符合国标的那种!
工业甲酰苯胺 2024-06-23 10:33:02 阅读 94
01、什么是枚举Enum?
枚举Enum
是在多种语言中都有的一种数据类型,用于表示一组特定相关的常量数据集合,如性别(男、女)、数据状态(可用、禁用)、垂直对齐(顶端、居中、底部)、星期等。特点是数据值固定,不会变,存储和显示的内容不同。
然而在JavaScript中并没有枚举Enum
类型,TypeScript算是有(本文中暂没用用TS的枚举)。在前端项目中还是会用到经常用到这类型数据的,本文就对枚举做一个通用封装,并进行尽量全局的总结。
先来看看最常用的性别:
❓你的系统中性别用的什么存储的呢?
在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>
效果:
总结
其实本质上就是设计一个标准的数据结构,能够方便的获取所有枚举数据项,然后根据值快速获取显示的文本。
文章转载自:安木夕
原文链接:https://www.cnblogs.com/anding/p/17627416.html
体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。