在Vue前端項目中,附件展示的自定義組件開發
- 2021 年 10 月 28 日
- 筆記
- 循序漸進VUE+Element
在Vue前端介面中,自定義組件很重要,也很方便,我們一般是把一些通用的介面模組進行拆分,創建自己的自定義組件,這樣操作可以大大降低頁面的程式碼量,以及提高功能模組的開發效率,本篇隨筆繼續介紹在Vue&Element前端項目中如何使用自定義封裝的組件,實現附件的展示場景。
1、介面模組的拆分
Vue的前端介面,對介面內容部分可以根據需要進行適當的拆分,也可以把通用的部分封裝為組件進行使用,如我在隨筆《循序漸進VUE+Element 前端應用開發(16)— 組織機構和角色管理模組的處理》中介紹過機構或角色資訊中,介面內容比較多,可以進行拆分,根據內容的展示不同,拆分為各自的組件模組,然後合併使用即可,如下所示。
在對象UML的圖例中,應該是如下所示的效果圖,組織機構包含組織成員和角色的內容。

在介面上,組織成員還需要添加成員的功能,同理角色也需要添加角色的處理,如下UML圖示。


角色介面模組UML類圖如下所示。

那麼對應介面元素上,我們就應該以不同的Tab來展示這些資訊,如下所示。 其中可以看到不同的Tab顯示不同的內容。

完成添加成員、添加角色的介面組件後,我們就可以在組織機構介面裡面引入使用。

接著加入對應的組件集合裡面即可。

然後在介面部分加入對應的組件呈現程式碼,如下所示。

2、通用組件的拆分
前面介紹了按頁面內容進行的組件封裝處理,有時候,我們也可以根據特定功能的內容進行組件封裝,這樣我們就簡化了介面的呈現處理邏輯,只需要傳遞一定的參數給它即可。
如我在隨筆《使用Vue-TreeSelect組件實現公司-部門-人員級聯下拉列表的處理》中對樹列表功能的封裝,使用起來程式碼就很簡單,賦值相關的參數即可。
<treeselect :options="myDeptTree" v-model="addForm.dept_ID" :searchable="false" :default-expand-level="Infinity" :open-on-click="true" :open-on-focus="true" @input="updateDeptUser" :normalizer="normalizer" placeholder="所屬部門" />

以及在隨筆《自定義Vue&Element組件,實現用戶選擇和顯示》實現選擇用戶資訊的處理組件。

選擇用戶的彈出介面如下所示,其中可以根據部門分類、崗位分類進行快速的查詢,同時也可以根據用戶名進行查詢。

而如果我們這個組件通過v-modal綁定的值,如下介面程式碼所示
<select-post-user v-if="isEdit" ref="editForm.participant" v-model="editForm.participant" />
還有自定義字典組件的處理,在隨筆《在Vue&Element前端項目中,對於字典列表的顯示處理》中介紹。

而使用程式碼如下所示。
<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>
3、附件展示的自定義組件開發
一般情況下,我們管理的附件都是諸如圖片、Excel文件、PDF文件等附件的管理。
附件表是一個綜合管理這些文件的記錄表,雖然附件一般是獨立上傳到伺服器端的文件系統裡面,不過也需要記錄這些文件的名稱、類別名稱、大小、後綴名、創建時間、創建人等資訊。
資料庫設計表如下所示。

記錄明細大概如下所示。

為了管理好這些文件資訊,我們在介面提供一些條件供查詢,如下是管理介面。

以上是附件的統一管理介面,我們在實際業務中很多業務表都可能用到附件資訊,因此可以在業務表中增加一個字元串欄位,用來存儲附件組的GUID,如下所示。

上面餓AttachGUID對應FileUpload表中的AttachmentGuid,可以用來獲得一個獲得多個附件列表。
我們先來看看業務表單中展示附件的效果,如下所示。

由於我們要獲取附件列表,輸入參數應該是附件分組的AttachGUID,輸出就是顯示文件或者圖片列表,圖片方便展示即可,文件則提供連接地址下載查看等。
那麼我們就需要根據這個場景來定義我們的附件展示組件了。封裝好的附件展示介面組件的使用程式碼如下所示。
<el-form-item label="附件"> <my-attachment v-modal="viewForm.attachGUID" /> </el-form-item>
程式碼非常簡單,就和使用其他原生組件是差不多的,而我們可以在各個模組用到附件的地方都如此展示,這樣處理不僅簡化了展示程式碼,而且不用關心太多的處理邏輯,確實很方便的。
那我們現在來看看,這個附件展示的自定義組件是如何工作的。
附件展示的程式碼如下所示,主要就是區分是圖片,還是常規文件進行不同的展示。
<template> <div style="box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1)"> <template v-if="!attachFiles || attachFiles.length == 0"> <el-empty :description="placeholder" :image-size="50" /> </template> <template v-else> <template v-for="(item, index) in attachFiles"> <el-image v-if="isImage(item)" :key="index" style="padding:5px;width: 100px; height: 100px" :src="getUrl(item)" :preview-src-list="imageList" :z-index="3000" /> <el-link v-else :key="index" :href="getUrl(item)" :underline="false" target="_blank" style="padding:5px;"> <span>{{ item.fileName }}</span> </el-link> </template> </template> </div> </template>
對於附件的API操作,我們引入對應的封裝類如下所示。
// 引入API模組類方法 import fileupload from '@/api/system/fileupload'
為了傳入對應的參數值,我們定義兩個prop屬性,如下所示。
<script> // 引入API模組類方法 import fileupload from '@/api/system/fileupload' export default { name: 'MyAttachment', // 組件的名稱 props: { placeholder: { // 空白提示 type: String, default: '暫無數據' }, value: {// 接受外部v-model傳入的值 type: [String, Number], default: '' } },
另外,對於傳入的v-modal或者value值,需要監控watch它的變化,如果變化,我們觸發附件的獲取展示邏輯,如下程式碼所示。
data () { return { attachFiles: [], imageList: [], // 預覽圖片列表 keyword: this.value // 選中的值 } }, watch: { // 判斷下拉框的值是否有改變 keyword (val, oldVal) { // console.log(val, oldVal) if (val !== oldVal) { // 組件內對值變更後向外部發送事件通知 this.getData() this.$nextTick(() => { this.$emit('input', val) }) } }, value (val, oldVal) { // 監聽外部對props屬性變更,如通過ResetFields()方法重置值的時候 this.keyword = val } },
其中數據的獲取,主要是調用服務端API的處理,獲得對應的附件列表,並判斷是否為圖片進行添加即可。
methods: { getData () { // console.log(this.value) if (this.value && this.value !== '') { var param = { guid: this.value } fileupload.GetByAttachGUID(param).then(data => { this.attachFiles = data.result // 生成並添加預覽圖片列表 this.imageList = [] this.attachFiles.map(item => { if (this.isImage(item)) { var imageUrl = this.getUrl(item) this.imageList.push(imageUrl) } }) }) } },
這樣我們就把通用的附件管理介面,業務表附件的展示統一起來,實現了比較好的附件通用管理,和通用字典模組一樣,一旦完成了組件的封裝,使用起來非常簡單,程式碼也比較容易維護了。

組件的拆分和封裝,是我們前端開發中非常重要的部分,也是我們快速構建複雜頁面功能的,又能輕鬆應對的必殺技之一。


