Let me briefly share what I think is the most elegant packaging solution for the status code returned by the backend.

Preface

In front-end development, we often encounter situations where we need to display different labels and colors based on the status code returned by the backend. For example, we have a list of contracts, and the status in it represents various meanings. We need to display the corresponding labels and colors based on the value of status. Of course, for example, there is a search function, which also involves searching based on status. For example:

status label color
0 To be signed red
1 Taking effect green
2 be expired grey
3 Cancelled grey
4 Not active grey
5 Abolished grey
6 aborted grey

So, how would you write in this situation? Use v-if to judge? In fact, these things themselves do not have any technical difficulties. It is just that development thinking leads to different writing methods for everyone. Some people like to use calculated attributes to use various else if sets. Some people directly use the cv method. Every page will write the following as long as it is used. Code:

<div v-if="item.status === 0" :style="{ color: 'xxx' }">xxx</div>
<div v-if="item.status === 1" :style="{ color: 'xxx' }">xxx</div>
<div v-if="item.status === 2" :style="{ color: 'xxx' }">xxx</div>
<div v-if="item.status === 3" :style="{ color: 'xxx' }">xxx</div>
<div v-if="item.status === 4" :style="{ color: 'xxx' }">xxx</div>
<div v-if="item.status === 5" :style="{ color: 'xxx' }">xxx</div>
<div v-if="item.status === 6" :style="{ color: 'xxx' }">xxx</div>

As a result, a set of business is written down, and there are a lot of pages that use this. Suddenly one day, the backend guy tells you: I have added the xxx status to this status, please add it. How should you respond? What? You mean batch replacement? Then if your layout is different, the following situation will occur on a certain page:

<span v-if="item.status === 1" :style="{ color: 'xxx' }">xxx</span>
<span v-if="item.status === 0" :style="{ color: 'xxx' }">xxx</span>
<span v-if="item.status === 2" :style="{ color: 'xxx' }">xxx</span>
<span v-if="item.status === 3" :style="{ color: 'xxx' }">xxx</span>
<span v-if="item.status === 4" :style="{ color: 'xxx' }">xxx</span>
<span v-if="item.status === 5" :style="{ color: 'xxx' }">xxx</span>
<span v-if="item.status === 6" :style="{ color: 'xxx' }">xxx</span>

What is written in each place may have slight discrepancies due to various reasons, resulting in the inability to replace it in batches. And the function related to searching based on status code cannot be replaced. So is there a simple and elegant encapsulation method that makes our code easier to maintain and reuse?

The answer is: yes! In this blog, I will introduce you to a solution that uses class methods to encapsulate the option list, so that you can get the value of any attribute, whether it is a label or a color, with one line of code. The benefits of doing this are:

  • You can encapsulate related data and logic in a class to improve cohesion .
  • You can use inheritance and polymorphism to extend or rewrite this class to implement more functions or adapt to more scenarios.
  • You can use constructors or static methods to initialize or create instances of this class, increasing flexibility .

define an interface

First, we need to define an interface that represents the options object. An options object contains three attributes: label, value, and style. We can use TypeScript to define this interface, as follows:

// 定义一个接口,表示选项对象
interface IOptionItem<T> {
    
    
    label: string;
    value: T;
    style?: CSSProperties;
}

copy

Note that we use a generic parameter T to represent the type of value, so that we can make this interface support different types of values, such as numbers, strings, Boolean values, etc.

Define a generic class

Next, we need to define a generic class that represents the list of options. An options list contains a private property options (option array), and a public method get (get the corresponding property based on the value). We can use TypeScript to define this generic class as follows:

// 定义一个泛型类,表示选项列表
class OptionList<T> {
    
    
    // 存储选项列表
    options: IOptionItem<T>[] = [];

    // 定义一个构造函数,接收一个选项列表作为参数
    constructor(optionList: IOptionItem<T>[]) {
    
    
        this.options = optionList;
    }

    // 定义一个通用方法,根据值获取对应的属性
    public get<K extends keyof IOptionItem<T>>(value: T, key: K) {
    
    
        return this.options.find(v => v.value === value)?.[key];
    }
}

copy

Note that we use a generic parameter T to represent the type of option list, so that we can make this class support different types of option lists, such as numbers, strings, Boolean values, etc. We also use a generic parameter K to represent the attribute name of the option object, so that we can let this method return the value of any attribute, such as label, value, style, etc.

Create an instance of a choice list

Finally, we need to create an instance of the options list to store the contract state options and colors. We can use TypeScript to create this instance as follows:

// 创建一个选项列表的实例
const contractStatusOptions = new OptionList<number>([
    {
    
     label: "待签约", value: 0, style: {
    
     color: "red",'--bg-color':'#1899ff' } },
    {
    
     label: "生效中", value: 1, style: {
    
     color: "green" } },
    {
    
     label: "已到期", value: 2, style: {
    
     color: "gray" } },
    {
    
     label: "已取消", value: 3, style: {
    
     color: "gray" } },
    {
    
     label: "未生效", value: 4, style: {
    
     color: "gray" } },
    {
    
     label: "已作废", value: 5, style: {
    
     color: "gray" } },
    {
    
     label: "已中止", value: 6, style: {
    
     color: "gray" } }
]);

copy

Note that we used the number type as the type of the option list because the value of the contract status is a number. We also added a style attribute to each options object to store the color.

Call common methods to get tags and styles

Now, we can use this instance to call the general method and get the corresponding label and style based on the status value. We can use TypeScript to call this method, as follows:

// 调用通用方法,获取标签和样式
contractStatusOptions.get(1, 'label'); // 生效中
contractStatusOptions.get(1, 'style'); // { color: "green" }

copy

Note that we passed in two parameters: state value and attribute name. In this way, we can get the value of any attribute, whether it is a label or a color, with one line of code.

Summarize

In this article, I introduce you to a way to encapsulate a list of options with a class method, so that you can get the value of any attribute, whether it is a label or a color, with one line of code. The benefits of doing this are:

  • You can encapsulate related data and logic in a class to improve cohesion .
  • You can use inheritance and polymorphism to extend or rewrite this class to implement more functions or adapt to more scenarios.
  • You can use constructors or static methods to initialize or create instances of this class, increasing flexibility .

I hope you learned something useful from this article and can apply this packaging scheme in your own projects. If you have any questions or ideas or have a more suitable packaging solution, welcome to discuss!

Guess you like

Origin blog.csdn.net/wz9608/article/details/132113855