经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Vue.js » 查看文章
优雅使用前端枚举Enum,符合国标的那种!
来源:cnblogs  作者:安木夕  时间:2024/2/28 9:14:12  对本文有异议

image.png

01、什么是枚举Enum?

枚举Enum是在多种语言中都有的一种数据类型,用于表示一组特定相关的常量数据集合,如性别(男、女)、数据状态(可用、禁用)、垂直对齐(顶端、居中、底部)、星期等。特点是数据值固定,不会变,存储和显示的内容不同。

然而在JavaScript中并没有枚举Enum类型,TypeScript算是有(本文中暂没用用TS的枚举)。在前端项目中还是会用到经常用到这类型数据的,本文就对枚举做一个通用封装,并进行尽量全局的总结。

先来看看最常用的性别:

Text文字(界面显示) 编码(编码、传输、存储使用) 数字值(存储使用)
male/man/M 1
female/woman/F 2
其他 other 3

?你的系统中性别用的什么存储的呢?

  • 在UI上显示为Text文字描述,如表格、单选项。
  • 传输或存储时,一般会用一个有意义的字符编码,或者数字,两种方式都有也都可以。
  • 如果数据量少,可以用字符编码,如M(男)、Male(男),可读性更好,就是占用空间比数字类型多。
  • 推荐采用短整形数字表示,存储空间更小,采用一个字节的最小整形即可(值为0到255)。

image.png

针对性别的枚举值,其实是有国家标准的,国标中就是用的整数值标识。

??参考国标:GB/T 2261.1-2003 个人基本信息分类与代码 第1部分:人的性别代码(可在线预览),早在2003年就颁布了。

image.png

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


02、前端应用场景

人员选择-选择bug2.gif

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

image.png

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

image.png

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

image.png


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函数。
  1. /**
  2. * 枚举创建工厂(构造函数),扩展枚举对象:keys、values(含key值的[{key,text,type}])、formatter。
  3. * @param {*} enumObj 枚举值,支持标准模式{key:{text,type},},简单模式{key:text,}(会自动转换为标准模式)
  4. * @param {*} keyParseFunc key的转换函数,默认null,如果key为整数则传 parseInt
  5. */
  6. export default function EnumFactory(enumObj, keyParseFunc = null) {
  7. //复制(继承)enumObj
  8. Object.assign(this, enumObj)
  9. // keys:枚举的key集合[key]
  10. Object.defineProperty(this, 'keys', {
  11. value: keyParseFunc ? Object.keys(enumObj).map(s => keyParseFunc(s)) : Object.keys(enumObj)
  12. })
  13. // 处理 values
  14. let values = []
  15. const ovalues = Object.values(enumObj)
  16. // 主要区分下value是简单类型(字符串)还是对象类型
  17. if (typeof ovalues[0] === 'string') {
  18. ovalues.forEach((text, index) => {
  19. const obj = { key: this.keys[index], text }
  20. values.push(obj)
  21. this[this.keys[index]] = obj
  22. })
  23. }
  24. else {
  25. ovalues.forEach((item, index) => {
  26. item.key = this.keys[index]
  27. values.push(item)
  28. })
  29. }
  30. // 设置values属性
  31. Object.defineProperty(this, 'values', { value: values })
  32. // formatter:element中表格绑定枚举数据文本的formatter函数
  33. // r、c为行列,可传入null
  34. Object.defineProperty(this, 'formatter', {
  35. value: function(r, c, value) {
  36. return values.filter(v => v.key == value || v.text == value)[0]?.text || 'notfound'
  37. }
  38. })
  39. //枚举定义的数据都是常量,不可修改,冻结一下
  40. Object.freeze(this)
  41. }

3.2、基于EnumFactory定义枚举值

创建一个enums.js存放常用枚举常量:

  • 性别枚举对象(key为整数)
  • 使用状态
  • 对齐方式
  1. import EnumFactory from "@/utils/enumFactory";
  2. /**
  3. * 性别枚举对象(key为整数)
  4. */
  5. export const enumGender = new EnumFactory({
  6. 1: { text: '男', type: 'priary' },
  7. 2: { text: '女', type: 'warning' },
  8. 9: { text: '其他', type: 'info' },
  9. },parseInt)
  10. /**
  11. * 使用状态
  12. */
  13. export const enumUse = new EnumFactory({
  14. enable: { text: '启用', type: 'success' },
  15. disable: { text: '禁用', type: 'danger' }
  16. })
  17. // 对齐方式
  18. const enumAlign = new EnumFactory({ left: '左', middle: '中', right: '右' })

enumGender的结构如下:

image.png

  • 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

  1. <el-table :data="table">
  2. <el-table-column label="姓名" prop="name" width="220px"></el-table-column>
  3. <el-table-column label="性别" prop="gender" align="center" width="120px">
  4. <template slot-scope="scope">
  5. <el-tag :type="enumGender[scope.row.gender]?.type">{{ enumGender[scope.row.gender]?.text }}</el-tag>
  6. </template>
  7. </el-table-column>
  8. <el-table-column label="方向" prop="align" :formatter="enumAlign.formatter" width="120px"></el-table-column>
  9. <el-table-column label="状态" prop="use" align="center" width="120px">
  10. <template slot-scope="scope">
  11. <el-tag :type="enumUse[scope.row.use]?.type">{{ enumUse[scope.row.use]?.text }}</el-tag>
  12. </template>
  13. </el-table-column>
  14. </el-table>

效果:

image.png

2、直接显示枚举值的(中文)描述信息+样式,用type来绑定状态样式。

  1. <el-form-item label="状态标签-all">
  2. <el-tag v-for="tag in enumGender.values" :key="tag.key" :type="tag.type" style="margin-right: 10px;">
  3. {{tag.text }}
  4. </el-tag>
  5. </el-form-item>
  6. <el-form-item label="状态标签-值">
  7. <el-tag :type="enumGender[value]?.type">{{ enumGender[value]?.text }} : {{ value }}</el-tag>
  8. </el-form-item>

效果:

image.png

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

??用enumAlign.values作为源来绑定

  1. <el-form-item label="下拉选择">
  2. <el-select v-model="value">
  3. <el-option v-for="e in enumAlign.values" :key="e.key" :value="e.key" :label="e.text"></el-option>
  4. </el-select>
  5. </el-form-item>
  6. <el-form-item label="单选组1">
  7. <el-radio-group v-model="value">
  8. <el-radio-button v-for="item in enumAlign.values" :key="item.key" :label="item.key">{{ item.text }}</el-radio-button>
  9. </el-radio-group>
  10. </el-form-item>
  11. <el-form-item label="单选组2">
  12. <el-radio-group v-model="value">
  13. <el-radio v-for="item in enumAlign.values" :key="item.key" :label="item.key">{{ item.text }}</el-radio>
  14. </el-radio-group>
  15. </el-form-item>

效果:

image.png


总结

其实本质上就是设计一个标准的数据结构,能够方便的获取所有枚举数据项,然后根据值快速获取显示的文本。


参考资料


??版权申明:版权所有@安木夕(kanding),本文内容仅供学习,欢迎指正、交流,转载请注明出处!
原文编辑地址:https://www.yuque.com/kanding

原文链接:https://www.cnblogs.com/anding/p/17627416.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号