在Vue前端項目中,附件展示的自定義組件開發

在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)
            }
          })
        })
      }
    },

這樣我們就把通用的附件管理界面,業務表附件的展示統一起來,實現了比較好的附件通用管理,和通用字典模塊一樣,一旦完成了組件的封裝,使用起來非常簡單,代碼也比較容易維護了。

 

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