前端如何優雅地使用列舉

2021-10-19 04:09:42 字數 4176 閱讀 2911

在前端開發中我們經常遇到這樣一種情況:假設我們要渲染乙個訂單列表,後端返回的資料中包含這樣乙個字段:

// 訂單狀態

orderstatus:

0

後端可能會告訴我們,它對應後端的這樣一組值:

那麼我們在前端如何優雅地把後端所返回的值0轉換成字串已完成呢?這就是本文要討論的問題。

為了引出我們的方案,我們先來看乙個常用但不那麼優雅的方案:

首先,我們來為這個字段定義乙個物件

接下來,根據返回的字段值從物件中取出對應的值即可:

(string

(orderstatus));

// 已完成

缺乏靈活性

封裝性較差,不利於擴充套件

關於靈活性,我們嘗試換乙個場景:假設我們現在需要根據中文文本來獲取它對應的value,該怎麼辦呢?我們可能會定義下面這樣乙個物件:

我相信任何乙個有開發經驗的開發者看到這樣的**都會嗤之以鼻,畢竟用中文字串作物件的key實在太瘋狂了(儘管這在js中是允許的)!

面對這個場景,我們定義的那個『單薄』的物件已經完全不夠用了。簡單場景看起來很美好,但現實卻總是很複雜!

關於這個方案的其他缺點我們不再一一枚舉,我們接下來介紹一種更加優雅的方案:

歷史常識告訴我們,當乙個地區變得混亂,多半是管理出了問題,上述問題也一樣。為了解決混亂,我們嘗試引入乙個「管理者」,來管理這個列舉字段。

在實現這個「管理者」之前,我們先來思考這個管理者應該具備哪些能力。這裡我們把後端返回的值0,1,2稱為value,把對應的中文文字稱為label

首先,它必須能同時具備根據value獲取label,以及根據label獲取value的能力,為了提供更大的靈活性,它最好可以以陣列的形式暴露出所有的valuelabel,以便我們列舉,於是它的結構大概是這樣的(這裡只列舉了最基本的屬性和方法):

const orderstatusenummanager =

,getvaluebylabel

(value)

,}

我們定義的這兩個get方法的搜尋邏輯是:根據傳入的value找到它在values陣列中的索引,然後取出labels中對應位置的值即可,反之亦然。這樣我們就解決了上述第乙個不夠靈活的問題。

當然,作為乙個優雅的解決方案,我們肯定不會乙個個手寫每個列舉欄位的管理者物件?所以我們來定義乙個工廠函式:

// 用於構造列舉欄位的管理者物件

// name是http傳輸時列舉值的欄位名,根據需要可以不要

function

getenummanager

(name, enums)

,getlabelbyvalue

(value: any)

,getitembyvalueorlabel

(valueorlabel: string | number |

null

)return enums[index];}

,...

// 其他專用取值函式

}}

現在我們可以這樣生成乙個管理者物件:

const orderstatusenum =

getenummanager

('orderstatus',[

,,])

用這個管理者物件,我們可以很容易相互對映value和label:

orderstatusenum.

getlabelbyvalue(0

);// 已完成

orderstatusenum.

getvaluebylabel

('已完成');

// 0

我們可以很容易地列舉所有label,或者所有value:

for=

"label in orderstatusenum.labels"

:key=

"label"

>

}<

/div>

for=

"value in orderstatusenum.values"

:key=

"value"

>

}<

/div>

當然它最大的魅力在於非常容易擴充套件,比如我們上面提到需要給三個值分別顯示綠色、橙色和灰色,以及支援不同的操作:

const orderstatusenum =

getenummanager

('orderstatus',[

,,])

你有兩種方式可以獲取這裡的coloroperation的值,一是直接從暴露出的enums屬性中提取:

// 查詢已完成的顏色值

const value =0;

const target = orderstatusenum.enums.

find

(order =>

order.value === value)

;console.

log(target ? target.color ||'')

;

還有另外一種方法,我們給管理者物件新增乙個用於獲取顏色的方法:

function

getenummanager

(name, enums)

return enums[index]

.color;}}

}

現在你可以這樣獲取0或者已完成對應的顏色值:

// 根據value取值

const color = orderstatusenum.

getcolorbyvalueorlabel(0

);// green

// 根據label取值

const color = orderstatusenum.

getcolorbyvalueorlabel

('已完成');

// green

所以,它需要擴充套件多少功能,取決於你需要新增多少!

我們把上述所有**封裝在乙個js檔案中,就可以作為全域性的工具使用了:

enums.js

// 用於構造列舉欄位的管理者物件

// name是http傳輸時列舉值的欄位名,根據需要可以不要

function

getenummanager

(name, enums)

,getlabelbyvalue

(value: any)

,getitembyvalueorlabel

(valueorlabel: string | number |

null

)return enums[index];}

,...

// 其他專用取值函式}}

export

const orderstatusenum =

getenummanager

('orderstatus',[

,,])

;export

const paytypeenum =

...// ...

在元件中使用它非常簡單:

import

from

'@/utils/enums.js'

;...

const tabeldata = res.data.

map(item =>

, item,)}

)

現在**的每一項新增了乙個字段label,對應的就是訂單狀態的中文文字,可以直接拿來渲染!

通過建立這個管理者物件,我們不僅實現了對列舉值的封裝和隔離,還很大程度地增加了它的擴充套件性和靈活性,建議大家可以在日常開發中嘗試使用它。

優雅地使用列舉enum

在開發中,我們可能會遇到這樣的問題 某乙個物件的某些字段比如常見的 的狀態,欄位名字叫 status,在資料庫中儲存的時候存的值一般是數字,比如 0 未處理 1 已處理 2 已取消 在介面展示的時候,我們不可能直接將數字展示,需要將它的實際含義進行對應展示,以前的自己 可能會這樣寫 未處理 已處理已...

前端如何優雅地顯示 JSON

json.cn 是我們開發過程中,經常用來格式化顯示json字串的工具 那麼如何在自己編寫的前端介面顯示同樣風格的 格式化之後json字串呢?網上流傳的版本顯示出來效果並不盡如人意,因此小改了一下。pre csspre string number boolean null key jssyntaxh...

SpringBoot如何優雅地使用Swagger2

spring boot 框架是目前非常流行的微服務框架,我們很多情況下使用它來提供 rest api。而對於 rest api 來說很重要的一部分內容就是文件,swagger 為我們提供了一套通過 和註解自動生成文件的方法,這一點對於保證 api 文件的及時性將有很大的幫助。本文將使用 swagge...