基於Vue的工作流項目模組中,使用動態組件的方式統一呈現不同表單數據的處理方式

在基於Vue的工作流項目模組中,我們在查看錶單明細的時候,需要包含公用表單資訊,特定表單資訊兩部分內容。前者表單數據可以統一呈現,而後者則是不同業務的表單數據不同。為了實現更好的維護性,把它們分開作為兩部分處理,但是頁面入口設計為統一的呈現頁面,這裡介紹使用動態組件的方式統一呈現不同表單數據的處理方式。

1、表單數據分類

剛才提到,表單數據按內容區分分為了兩類:通用業務表單、特定業務表單

如果我們要把兩者統一在一個通用頁面中進行展示,就需要根據不同表單名稱,動態載入屬於特定表單的展示模組,也就是動態組件的實現方式,大概的業務規則如下所示。

表單查看的實際效果介面如下所示。

 

2、動態組件的實現

首先我們需要在前端的路由器集合中加入一個路由地址的配置,以便定位到統一查看錶單頁面明細的路徑,如下所示。

  '_viewDetail': {
    path: '/_viewDetail',
    meta: {
      title: '查看申請單資訊'
    },
    component: Layout,
    children: [{
      path: '',
      component: () => import('@/views/workflow/system/viewdetail')
    }]
  },

完成後,我們開始編寫頁面,包含兩部分,一部分是通用的表單資訊

 

 一部分是動態組件構建的特定表單資訊,如下組件程式碼所示

    <!--實現動態組件的展示-->
    <component :is="viewType" :applyid="applyid" />

在我們平時使用vue中的模板的時候,許多時候都是直接定義成一個固定的模板,但是,vue中提供了一個動態模板,可以在任意模板中切換,就是用vue中<component>用:is來掛載不同的組件。

而其中viewType 是一個屬性定義,我們可以通過後台API獲取對應的模組名稱

  methods: {
    getViewType () {
      if (this.applyid) {
        // 通過申請單的DataTable去掉前綴,轉換小寫,獲得模組名稱,如TW_Payment => payment
        var param = { applyId: this.applyid }
        apply.GetModuleName(param).then(data => {
          if (data.result) {
            this.viewType = data.result.toLowerCase()
          }
        })
      }
    },

而其中viewType就是我們組件的名稱,這裡能夠呈現出來的內容,必須是這些組件已經註冊到全局中去了,就類似我們在Vue 項目中使用Element組件一樣,之所以可以使用它也是它已經全局註冊了(或者以組件方式載入到頁面)。

而我們定義的表單內容可能很多,如下目錄所示。

手工載入這些組件,難免遺漏或者錯誤,因此需要考慮按一定的規則動態載入進去系統中使用。

我們編寫一個js文件,用於動態獲取指定目錄下的vue組件,並使用Vue.component 動態安裝所需組件到系統中,如下程式碼所示。

export default {
  install(Vue) {
    // 從模組目錄中自動載入模組內容
    const viewFiles = require.context('./view', true, /\.vue$/)
    const viewModules = viewFiles.keys().reduce((viewModules, modulePath) => {
      // set './app.vue' => 'app'
      const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1').toLowerCase()
      const value = viewFiles(modulePath)
      viewModules[moduleName] = value.default
      return viewModules
    }, {})

    // console.log(viewModules)
    Object.keys(viewModules).forEach(key => {
      // console.log(key)
      Vue.component(key, viewModules[key])
    })

  }
}

然後我們在main.js中調用它安裝所需組件即可,如下程式碼所示。

// 導入工作流查看、創建等模組
import workflow from './views/workflow/modules'
Vue.use(workflow)

這樣我們就完成了組件的動態載入安裝,在通用的查看頁面中,就可以通過component的 is 方式動態呈現不同頁面表單的數據了。

以支付申請表單為例,我們的payment.vue組件程式碼如下所示。

<template>
  <div class="app-container">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>付款申請單-表單數據</span>
      </div>
      <el-form ref="viewForm" :model="viewForm" label-width="120px">
        <el-tabs value="basicPage" type="border-card">
          <el-tab-pane name="basicPage" label="基本資訊">
            <el-row>
              <el-col :span="24">
                <el-form-item label="付款事由">
                  <el-input v-model="viewForm.reason" readonly />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="付款金額">
                  <el-input v-model="viewForm.payAmount" readonly>
                    <span slot="suffix"></span>
                  </el-input>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="付款方式">
                  <el-input v-model="viewForm.payType" readonly />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="付款日期">
                  <el-date-picker v-model="viewForm.payDate" align="right" type="datetime" placeholder="選擇日期"
                    value-format="yyyy-MM-dd HH:mm:ss" readonly />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="收款人全稱">
                  <el-input v-model="viewForm.payeeFullName" readonly />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="銀行帳號">
                  <el-input v-model="viewForm.bankAccount" readonly />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="開戶行">
                  <el-input v-model="viewForm.bank" readonly />
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="備註資訊">
                  <el-input v-model="viewForm.note" readonly type="textarea" :rows="5" />
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="附件">
                  <my-attachment v-model="viewForm.attachGUID" />
                </el-form-item>
              </el-col>
            </el-row>
          </el-tab-pane>
        </el-tabs>
      </el-form>
    </el-card>

    <div class="dialog-footer">
      <el-button type="success" @click="goback">返回列表頁面</el-button>
    </div>
  </div>
</template>

並在js程式碼中定義了prop屬性applyid,如下所示。

  props: {
    applyid: {// 申請單ID, 接受外部v-model傳入的值
      type: [String, Number],
      default: ''
    }
  },

這樣我們在頁面創建的時候,就可以根據applyid來獲得對應的特定表單數據,然後頁面內容就會正常展示了。

  created () {
    this.getData() // 顯示數據
  },
  methods: {
    getData () {
      if (this.applyid) {
        var param = { applyId: this.applyid }
        payment.FindByApplyId(param).then(data => {
          // console.log(data)
          Object.assign(this.viewForm, data.result)
        })
      }
    }

表單查看的實際效果介面如下所示。

這樣就完成了我們通過統一的展示頁面,展示不同表單數據的統一操作。

 

查看頁面的操作,都通過路由名稱_viewdetail實現了統一的跳轉。

      <!--表格行操作按鈕 -->
      <el-table-column align="center" label="操作" width="110">
        <template scope="scope">
          <el-row>
            <el-button-group>
              <el-tooltip effect="light" content="查看" placement="top-start">
                <el-button icon="el-icon-search" type="success" circle size="mini"
                  @click="showView(scope.row.apply_ID)" />
              </el-tooltip>
              <el-tooltip effect="light" content="刪除" placement="top-start">
                <el-button icon="el-icon-delete" type="danger" circle size="mini" @click="showDelete(scope.row.id)" />
              </el-tooltip>
            </el-button-group>
          </el-row>
        </template>
      </el-table-column>

JS程式碼如下

    showView (id) { // 顯示查看對話框處理
      this.$router.push(
        {
          path: `/_viewDetail`, // 查看申請單路徑,以_view開始
          query: { id: id }
        })
    },

以上就是在Vue的工作流項目模組中,使用動態組件的方式統一呈現不同表單數據的處理方式,希望對您有所啟發,在一些特定的場景使用它,可以極大提高靈活性和開發效率。