在很多項目開發中,我們為了使用方便,一般都會封裝一些自定義組件來簡化界面的顯示處理,例如參照字典的下拉列表顯示,是我們項目中經常用到的功能之一,本篇隨筆介紹在Vue&Element前端項目中如何使用自定義封裝的字典顯示處理。
1、字典內容管理
我們在系統中,往往維護着一些系統常用到的字典信息,在我各個框架中都有一個通用的字典管理模塊,對於Vue&Element前端項目,也是一樣,我們也需要對它進行管理,方便前端使用。本篇隨筆介紹的內容適用於ABP開發框架的Vue&Element前端,微信框架和Bootstrap框架中的Vue&Element前端內容。
字典項目一般包括項目大類,字典項的管理,字典項包括顯示內容和值,兩者可以不一樣,也可以一樣,如下所示
或者如下所示
字典大類和字典項目的表設計圖如下所示。
字典大類由PID構建無窮級的樹結構,而字典項目則通過Name和Value來記錄顯示內容和值內容。
2、后端WebAPI的數據提供
在建立相關的數據表存儲數據外,我們后端也需要提供相應的Web API來給各前端提供數據處理,對於顯示處理,我們定義了一個適合於Select組件和Tree組件的數據結構,主要就是提供id和label的屬性,如下代碼所示。
/// <summary> /// 通用樹節點的定義 /// </summary> [Serializable] public class TreeNodeItem { /// <summary> /// 默認構造函數 /// </summary> public TreeNodeItem() { } /// <summary> /// 構造函數 /// </summary> public TreeNodeItem(CListItem item) :this() { this.Label = item.Text; this.Id = item.Value; } /// <summary> /// 參數化構造CListItem對象 /// </summary> /// <param name="label">顯示的內容</param> /// <param name="id">實際的值內容</param> /// <param name="key">存儲額外的鍵</param> public TreeNodeItem(string id, string label, string key = null) : this() { this.Id = id; this.Label = label; this.Key = key; } /// <summary> /// 參數化構造CListItem對象 /// </summary> /// <param name="label">顯示的內容</param> /// <param name="id">實際的值內容</param> /// <param name="key">存儲額外的鍵</param> public TreeNodeItem(int id, string label, string key = null) : this() { this.Id = id.ToString(); this.Label = label; this.Key = key; } /// <summary> /// 參數化構造CListItem對象 /// </summary> /// <param name="text">顯示的內容</param> public TreeNodeItem(string text) : this() { this.Id = text; this.Label = text; } /// <summary> /// 實際值內容 /// </summary> public string Id { get; set; } /// <summary> /// 顯示內容 /// </summary> public string Label { get; set; } /// <summary> /// 用於存儲額外的鍵 /// </summary> public string Key { get; set; } /// <summary> /// 子節點集合 /// </summary> [JsonProperty(NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)] public List<TreeNodeItem> children { get; set; } /// <summary> /// 返回顯示的內容 /// </summary> /// <returns></returns> public override string ToString() { return Label.ToString(); } }
有了這些數據結構,我們可以在Web API的控制器中提供相應的數據了。
而對於ABP框架后端,它們的調用方式也是類似的。
后端API執行返回的JSON數據結構如下所示。
有了這些數據,就需要在前端進行顯示即可。
3、Element 前端組件顯示
Vue&Element的前端,需要調用后端接口的時候,需要對API類進行一個簡單的封裝,這樣可以方便通過類的方式進行訪問后端接口。
前端界面組件中需要用到這個API調用的時候,import進來即可。
// 引入API模塊類方法 import dictdata from '@/api/system/dictdata'
有了提供的數據結構和API的封裝,我們可以在前端進行展示了,我們來看看Element的Select組件例子代碼
<template> <el-select v-model="value" placeholder="請選擇"> <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </template> <script> export default { data() { return { options: [{ value: '選項1', label: '黃金糕' }, { value: '選項2', label: '雙皮奶' }, { value: '選項3', label: '蚵仔煎' }, { value: '選項4', label: '龍須面' }, { value: '選項5', label: '北京烤鴨' }], value: '' } } } </script>
如果我們每次都需要用這個原始組件來進行展示,那么就需要編寫很多代碼,我們希望在編寫顯示字典列表的代碼時候,盡量減少代碼,因此我們定義了字典組件,用於接收兩個數據參數,一個是字典大類名稱,通過字典大類名稱獲取字典列表,並綁定的select組件中;另一個則是標准的集合列表。
我們來看看使用的界面效果和實際代碼。
而使用代碼如下所示。
<el-form-item label="付款方式" prop="payType"> <my-dictdata v-model="searchForm.status" type-name="付款方式" /> </el-form-item>
上面通過type-name來聲明字典大類,從而由組件邏輯實現數據源的綁定處理。
另一種方式就是綁定數據列表,通過options變量進行綁定,如下所示。
<el-form-item label="表單分類" prop="category"> <my-dictdata v-model="searchForm.category" :options="FormCategorys" /> </el-form-item>
而其中這個數據源則可以在頁面或者組件中實現獲取即可。
4、自定義組件處理
上面介紹了如何實現自定義字典組件,那么字典組件如何自定義處理呢,我們來看看一般的處理如下。
<template> <el-select v-model="keyword" filterable :clearable="clearable" :multiple="multiple" :disabled="disabled" :placeholder="placeholder" @change="change"> <el-option v-for="(item, index) in dictItems" :key="index" :label="item.label" :value="item.id"> <span style="float: left;color:yello;"> <i class="el-icon-tickets" style="color:blue;" /> {{ item.label }} </span> </el-option> </el-select> </template>
不過上面這種對於字符型的數據顯示沒問題,如果對於包含數值型的選項賦值,則會出現不匹配的問題,因此我們改進一下上面的選項處理代碼,以便適應字符型和數值型的綁定值處理。
<template> <el-select v-model="keyword" filterable :clearable="clearable" :multiple="multiple" :disabled="disabled" :placeholder="placeholder" @change="change"> <template v-for="(item, index) in dictItems"> <el-option v-if="typeof(keyword)=='string'" :key="index" :label="item.label" :value="'' + item.id" /> <el-option v-else-if="typeof(keyword)=='number'" :key="index" :label="item.label" :value="('' + item.id).trim() == '' ? '' : parseInt(item.id)" /> <el-option v-else :key="index" :label="item.label" :value="item.id" /> </template> </el-select> </template>
以上代碼通過判斷選項綁定的值類型,從而進行相應的處理,避免數據格式不一致的問題。
而其中的字典列表,這是通過判斷prop參數進行獲取處理的。
加載的時候,獲取數據進行顯示綁定即可。
以上就是我們進行用到的字典處理過程,包括后端提供數據API、前端對API的封裝,以及組件封裝,然后就是界面組件的調用,這種方式極大的提高了自定義組件的使用效率,簡化代碼,一旦我們封裝好自定義組件,使用起來非常方便。