1. 程式人生 > >循序漸進VUE+Element 前端應用開發(20)--- 使用元件封裝簡化介面程式碼

循序漸進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)--- 功能點管理及許可權控制  

循序漸進VUE+Element 前端應用開發(19)--- 後端查詢介面和Vue前端的整合

循序漸進VUE+Element 前端應用開發(20)--- 使用元件封裝簡化介面程式碼