3

基于Vue的工作流项目模块中,使用动态组件的方式统一呈现不同表单数据的处理方式

 2 years ago
source link: https://www.cnblogs.com/wuhuacong/p/15479305.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在基于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的工作流项目模块中,使用动态组件的方式统一呈现不同表单数据的处理方式,希望对您有所启发,在一些特定的场景使用它,可以极大提高灵活性和开发效率。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK