循序漸進VUE+Element 前端應用開發(20)--- 使用元件封裝簡化介面程式碼
VUE+Element 前端應用,比較不錯的一點就是介面元件化,我們可以根據重用的指導方針,把介面內容拆分為各個不同的組合,每一個模組可以是一個元件,也可以是多個元件的綜合體,而且這一個過程非常方便。元件封裝的目的就是為了能夠更加便捷、快速的進行業務功能的開發。元件(component)是vue的最強大功能之一,元件可以實現一些類似功能的複用及與其它業務邏輯的解耦。本篇隨筆介紹前端框架中常用到的一些元件封裝處理,用於簡化介面、隱藏實現細節的目的。
1、元件封裝的需要
在我們開發一個主要介面的時候,一般需要排列很多內容,各個部分的內容可能會在其他介面上比較常見,那麼這些如果是簡單的使用原始的Element介面元件,以及簡單的複製處理的話,頁面程式碼比較臃腫,而且隨著不斷的複製過去使用,各部分的介面又不在統一了。這個時候如果把那些相同的功能,抽象出來抽離成元件,通過元件引用方式就會顯得格外省事了。
在Winform開發中,我們知道有很多常見的使用者自定義控制元件,就是對常規介面內容的一些通用部分進行封裝,拖動過來即可使用。現在VUE+Element 前端應用的元件開發也很容易,把介面程式碼和Vue的控制邏輯JS程式碼組合一起形成一個小元件,通過使用Prop的方式傳入所需引數,由元件內部控制介面的展示邏輯及事件處理,那麼介面呼叫元件的時候就非常簡潔,這樣我們主頁面上的程式碼量就降低不少,也方便程式碼的維護。
例如對於常規的字典下拉列表,我們希望繫結一個字典型別就可以實現系統的下拉列表的顯示,那麼我們可以封裝這個常見的介面內容為一個字典元件。
還有對於樹列表及其過濾實現等常規的處理,我們也可以通過簡單的封裝,實現樹列表的展示,這樣我們傳入對應的樹列表資料即可呈現所需要的樹狀列表內容。
另外,還有一種情況,是介面內容太多,我們把它按內容劃分為不同的介面元件,然後頁面進行獨立的維護,主介面直接一行程式碼即可整合所需的內容板塊,極大減少主介面的程式碼鋪陳。
例如:對於許可權系統中的每個角色,除了包含基本資訊外,還會包含擁有的許可權(功能控制點)、包含使用者,以及擁有的選單,其中許可權是用來控制介面元素,如操作按鈕的顯示的,而擁有的選單,則是使用者以指定賬號登入系統後,獲得對應角色的選單,然後構建對應的訪問入口的。角色介面模組UML類圖如下所示。
那麼對應介面元素上,我們就應該以不同的Tab來展示這些資訊,每個Tab內容部分就可以作為一個獨立的介面元件來開發。
在比如,組織機構裡面新增成員和新增角色的操作UML圖。
其中新增成員、新增角色,涉及介面的列表資料展示以及對應的新增展示操作,獨立一個介面元件還是比較方便的,而且新增成員 ,在角色維護模組裡面也需要用到,那麼可以相容兩個場景來設計元件模組。
2、介面元件的封裝處理
在VUE+Element 的前端場景中,想要封裝好一個元件,一般要熟練掌握的三個技能:1、父元件傳值到子元件(props) 2、子元件傳值到父元件($emit)3、插槽使用(slot)。對於一個獨立的元件,props是用來為元件內部注入核心內容;$emit用來使這個元件通過一些操作來融入其它元件中。
我們來詳細分析下前面介紹的元件場景。
對於字典模組來說,一般如果需要實現和系統字典模組裡面的Api對接,並展示對應字典型別的下拉列表,實現程式碼如下所示。
<el-select v-model="searchForm.ProductType" filterable clearable placeholder="請選擇"> <el-option v-for="(item, key) in typeList" :key="key" :label="item.value" :value="item.key" /> </el-select>
然後在JS邏輯裡面使用字典的API獲取對應資料,然後繫結到typeList屬性上面即可。這樣的邏輯如果每個用到字典的地方都需要這樣處理,程式碼顯然比較臃腫,而且使用元件封裝更方便。
我們在Componen目錄下建立一個Common目錄,然後在其中新增一個my-dictdata.vue檔案,用來封裝字典內容處理的。
如果我們完成元件的編寫,那麼引用元件只需要一行程式碼即可實現相同的功能了。
<my-dictdata v-model="searchForm.ProductType" type-name="商品型別" />
以及在頁面的元件裡面引入這個自定義元件即可。
import myDictdata from '@/components/Common/my-dictdata' export default { components: { myDictdata },
如果為了簡便,也可以在main.js裡面統一全域性引入。
這樣相對於使用原始的Element介面元件,既有介面程式碼,又有JS程式碼,這樣的一行程式碼就實現功能,顯得非常簡潔。
為了瞭解其中的奧祕,我們對元件的開發過程進行簡單的瞭解,其中元件介面部分的程式碼如下所示,和上面的差不多。
<template> <el-select v-model="svalue" filterable clearable placeholder="請選擇"> <el-option v-for="(item, index) in dictItems" :key="index" :label="item.Text" :value="item.Value" > <span style="float: left;color:yello;"> <i class="el-icon-tickets" style="color:blue;" /> {{ item.Text }} </span> </el-option> </el-select> </template>
然後在JS部分引入字典操作的Api類,以及定義Prop屬性typeName,如下所示。
並對傳入Model值進行監控
我們在Mounted的實現裡面,增加對字典資料的請求繫結,如下所示。
對於樹形列表
一般來說它的使用程式碼如下所示。
還是可以感覺比較臃腫,如果放到主頁面裡面,會佔用很多程式碼行,維護起來也不方便,而且樹列表也是一個常見的介面展示內容,可以通過簡單的封裝進行減少主頁面的程式碼量。
同樣我們可以通過封裝一個樹列表元件
我們可以在my-tree.vue裡面定義很多常見的的Prop屬性,以方便呼叫的時候傳入對應的值來改變介面的呈現。
這樣主介面呼叫元件來實現功能的時候,只需要一行介面程式碼即可。
<myTree :data="treedata" icon-class="el-icon-price-tag" @nodeClick="nodeClick" />
相應的處理獲得treedata的操作,是下面的函式
getTree() { // 樹列表資料獲取 var param = { SkipCount: 0, MaxResultCount: 1000, Tag: 'web' // Web端專用 } menu.GetAll(param).then(data => { this.treedata = [];// 樹列表清空 var list = data.result.items if (list) { // 使用getJsonTree函式,實現對二維錶轉換為巢狀樹物件集合 var newTreedata = getJsonTree(list, { id: 'id', pid: 'pid', children: 'children', label: 'name' }); this.treedata = newTreedata } }); },
而對於部分頁面元件的方式,這種一般不是很通用的元件,一般我們可以把它放在同一個目錄上的Components目錄裡面,如下是許可權模組裡面用到的一些介面內容元件封裝。
完成新增成員、新增角色的介面元件後,我們就可以在組織機構介面裡面引入使用。
角色管理,我們也依據這個來對模組的內容進行劃分,不同業務設計不同的介面元件,最後整合一起使用即可。
<el-dialog title="檢視資訊" :visible="isView" :modal-append-to-body="false" @close="closeDialog"> <el-col> <el-tabs value="basicPage" type="border-card"> <el-tab-pane name="basicPage" label="基本資訊"> <el-form ref="viewForm" :model="viewForm" label-width="120px"> <el-form-item label="角色名"> <el-input v-model="viewForm.name" disabled /> </el-form-item> <el-form-item label="角色顯示名"> <el-input v-model="viewForm.displayName" disabled /> </el-form-item> <el-form-item label="角色描述"> <el-input v-model="viewForm.description" type="textarea" disabled /> </el-form-item> </el-form> </el-tab-pane> <el-tab-pane name="permitPage" label="許可權"> <rolefunction ref="rolefunction" :role-id="selectRoleId" /> </el-tab-pane> <el-tab-pane name="userPage" label="使用者"> <roleuser ref="roleuser" :role-id="selectRoleId" :can-add="false" :can-delete="false" /> </el-tab-pane> <el-tab-pane name="menuPage" label="選單"> <rolemenu ref="rolemenu" :role-id="selectRoleId" /> </el-tab-pane> </el-tabs> </el-col> <div slot="footer" class="dialog-footer"> <el-button type="success" @click="closeDialog">關閉</el-button> </div> </el-dialog>
或者
以上就是我們封裝一些常見通用元件,以及頁面模組的元件,主要的目的就是可以簡化主呼叫介面的程式碼,以及提高使用的效率。
為了方便讀者理解,我列出一下前面幾篇隨筆的連線,供參考:
循序漸進VUE+Element 前端應用開發(1)--- 開發環境的準備工作
循序漸進VUE+Element 前端應用開發(2)--- Vuex中的API、Store和View的使用
循序漸進VUE+Element 前端應用開發(3)--- 動態選單和路由的關聯處理
循序漸進VUE+Element 前端應用開發(4)--- 獲取後端資料及產品資訊頁面的處理
循序漸進VUE+Element 前端應用開發(5)--- 表格列表頁面的查詢,列表展示和欄位轉義處理
循序漸進VUE+Element 前端應用開發(6)--- 常規Element 介面元件的使用
循序漸進VUE+Element 前端應用開發(7)--- 介紹一些常規的JS處理函式
循序漸進VUE+Element 前端應用開發(8)--- 樹列表元件的使用
循序漸進VUE+Element 前端應用開發(9)--- 介面語言國際化的處理
循序漸進VUE+Element 前端應用開發(10)--- 基於vue-echarts處理各種圖表展示
循序漸進VUE+Element 前端應用開發(11)--- 圖示的維護和使用
循序漸進VUE+Element 前端應用開發(12)--- 整合ABP框架的前端登入處理
循序漸進VUE+Element 前端應用開發(13)--- 前端API介面的封裝處理
循序漸進VUE+Element 前端應用開發(14)--- 根據ABP後端介面實現前端介面展示
循序漸進VUE+Element 前端應用開發(15)--- 使用者管理模組的處理
循序漸進VUE+Element 前端應用開發(16)--- 組織機構和角色管理模組的處理
循序漸進VUE+Element 前端應用開發(17)--- 選單管理
循序漸進VUE+Element 前端應用開發(18)--- 功能點管理及許可權控制