前端为什么要使用枚举?(优化``if-else``版)

一、枚举的业务场景与遇到的问题

我们在日常业务开发中,经常遇到枚举,如商品状态、页面状态、审核状态等,翻阅以往的一些业务代码,会发现很多地方都是这么写的:

<span v-if="status == 0">审核中</span>
<span v-else-if="status == 1">审核通过</span>

以上代码其实存在以下问题:

魔数化:一旦有个数值改动,就得全局替换匹配

差语义化:无法直观通过值推导出含义 于是,进阶做法我们想的是通过引入常量,如:

<span v-if="status == STATUS.AUDITING">审核中</span>
<span v-else-if="status == STATUS.PASS">审核通过</span>

然而,我们其实还会遇到以下场景:

需要拿到枚举值获得枚举含义 特别是在列表中尤其常见。我们通常的做法是:建立过滤器,建立Map,如:

export default {
   
    // ...
    filters: {
   
        statusName: status => {
   
            const map = {
   
                [STATUS.AUDITING]: '审核中',
                [STATUS.PASS]: '审核通过'
            }
            return map[status] || ''
        }
    }
}

这样子虽然也挺方便,但是仍然不够完美:

定义隔离:枚举值和枚举含义分离,还是会带来一定维护上的问题

二 、如何改善?

我们期望的应该是定义能够一体化,而不是分散化。参考Java里的枚举做法,其实好很多:

public enum AgingTypeEnum {
   
    ALL(0, "全部"),
    SPECIAL(1, "特批时效"),
    PLATFORM(2, "平台定义");
    // ...
}

但是,虽然TS里也实现了enum,但其实做法还是有些不一样,还是不那么利于我们的业务场景。因为TS里的enum,也不是枚举值与含义定义一体化。对于我们的业务场景,可能下面这么做更利于我们的使用:

const STATUS = createEnum({
   
    AUDITING: [0, '审核中'],
    PASS: [1, '审核通过']
})

export default {
   
    // ...
    created() {
   
        this.STATUS = STATUS
    }
}

审核中 审核通过

<p>当前状态:{
   STATUS.getDescFromValue(syncData.status)}</p>
<p>也可用通过枚举名称获取描述:{
   STATUS.getDesc('AUDITING')}</p>

如此一来,具有以下好处:

  • 去魔数化:后端假如改了审核中状态为2,那么我们就只需要在开头把0改为2即可
  • 语义化:通过STATUS.AUDITING我们就可以大概猜出含义
  • 定义一体化:枚举值和枚举描述写在了一起,不分散
  • 使用方便:无需额外的过滤器,就可以通过枚举名称/枚举值获得枚举含义

三、实现

实现代码如下:

/**
 * 枚举定义工具
 * 示例:
 * const STATUS = createEnum({
 *     AUDIT_WAIT: [1, '审核中'],
 *     AUDIT_PASS: [2, '审核通过']
 * })
 * 获取枚举值:STATUS.AUDIT_WAIT
 * 获取枚举描述:STATUS.getDesc('AUDIT_WAIT')
 * 通过枚举值获取描述:STATUS.getDescFromValue(STATUS.WAIT)
 * 
 */

interface EnumDefinition {
   
    [enumName: string]: [number, string]
}

export default function createEnum(definition: EnumDefinition) {
   
    const strToValueMap = {
   }
    const numToDescMap = {
   }
    for (const enumName of Object.keys(definition)) {
   
        const [value, desc]: [number, string] = definition[enumName]
        strToValueMap[enumName] = value
        numToDescMap[value] = desc
    }
    return {
   
        ...strToValueMap,
        getDesc(enumName: string): string {
   
            return definition[enumName] && definition[enumName][1] || ''
        },
        getDescFromValue(value: number): string {
   
            return numToDescMap[value] || ''
        }
    }
}

非TS版本

export default function createEnum(definition) {
   
    const strToValueMap = {
   }
    const numToDescMap = {
   }
    for (const enumName of Object.keys(definition)) {
   
        const [value, desc] = definition[enumName]
        strToValueMap[enumName] = value
        numToDescMap[value] = desc
    }
    return {
   
        ...strToValueMap,
        getDesc(enumName) {
   
            return definition[enumName] && definition[enumName][1] || ''
        },
        getDescFromValue(value) {
   
            return numToDescMap[value] || ''
        }
    }
}

相关推荐

  1. 前端为什么使用?(优化``if-else``

    2024-01-19 11:14:01       34 阅读
  2. C. Messenger in MAC - 堆优化

    2024-01-19 11:14:01       23 阅读
  3. 类简单使用

    2024-01-19 11:14:01       37 阅读
  4. 为什么使用ElasticSearch?

    2024-01-19 11:14:01       26 阅读

最近更新

  1. 将pytorch 模型封装为c++ api 例子

    2024-01-19 11:14:01       0 阅读
  2. Rust: 关于Pin以及move前后分析

    2024-01-19 11:14:01       0 阅读
  3. LVS实验

    LVS实验

    2024-01-19 11:14:01      0 阅读
  4. 【Git】取消追踪多个文件或目录

    2024-01-19 11:14:01       0 阅读
  5. 环境变量Path

    2024-01-19 11:14:01       1 阅读
  6. 数据守卫者:sklearn中的异常点检测技术

    2024-01-19 11:14:01       1 阅读
  7. 概率解码:SKlearn中模型的概率预测指南

    2024-01-19 11:14:01       1 阅读
  8. 遇到的问题汇总

    2024-01-19 11:14:01       1 阅读
  9. Oracle中CREATE FORCE VIEW的说明和例子

    2024-01-19 11:14:01       1 阅读

热门阅读

  1. kafka入门(八):副本

    2024-01-19 11:14:01       33 阅读
  2. Python:正则表达式之re.group()用法

    2024-01-19 11:14:01       34 阅读
  3. postgreSQL之grant

    2024-01-19 11:14:01       28 阅读
  4. linux安装Zookeeper的详细步骤

    2024-01-19 11:14:01       36 阅读
  5. AWS Cognito 实战指南

    2024-01-19 11:14:01       30 阅读
  6. 云原生微服务:现代化应用开发的支柱

    2024-01-19 11:14:01       42 阅读
  7. SpringBoot 实现 PDF 添加水印有哪些方案

    2024-01-19 11:14:01       26 阅读
  8. Linux/Uinx Makefile介绍以及使用方法和代码演示

    2024-01-19 11:14:01       29 阅读