在我們一些系統里面,有時候會需要一些讓用戶自定義的數據信息,一般這些可以使用擴展JSON進行存儲,不過每個業務表的顯示項目可能不一樣,因此需要根據不同的表單進行設計,然后進行對應的數據存儲。本篇隨筆結合基於Vue+Element實現動態表單的設計、數據錄入存儲的相關操作。
1、動態表單的設計
動態表單的設計一般是基於某個能夠動態設計界面的方式實現的,界面上定義對應的說明以及錄入數據的方式,如標簽后面加上文本,或者多文本等方式。由於我們后台是強類型的數據實體,后端一般不采用動態修改數據庫字段的方式構建,而是采用擴展JSON結構的方式來定義整個動態表單的結構,動態擴展的JSON結構比較彈性,不用可以隨時移除,也可隨時增加,非常方便,這是一樣常見的處理數據結構方式。
表單設計器有很多組件可以使用
不過我傾向於使用前者vue-form-making,因為它提供一個設計器的組件,可以集成在項目中使用,而form-generator好像沒有找到,只有在線的設計器。不過兩者的概念都差不多。
vue-form-making的設計器界面如下:
而form-generator設計器界面如下,和前者不同的是,這個沒有提供組件可以集成在項目里面。
有了工具,我們就要考慮如何處理我們具體項目里面表的擴展表單界面的設計工作了。
我們設計一個表單用來存儲對應的業務表的結構設計,然后在具體表的查看、新增、編輯界面里面,根據鍵值標識獲取對應的動態表單界面,整合到我們實際的界面里面,給用戶查看或者錄入、編輯等。
因此我們在系統模塊里面增加一個動態表單的功能入口,以便設計系統所需業務表單的界面結構。
這里存儲的信息不多,主要就是一個用來區分表單名稱的鍵和說明信息,以及JSON界面結構信息即可 。
這里【立即編輯】功能就是前面說到的整合表單設計界面的入口。
其中使用making-form的代碼如下所示,自定義了保存的操作功能。
<el-dialog title="創建表單" :close-on-click-modal="false" :append-to-body="true" :visible="isShowForm" fullscreen @close="isShowForm=false"> <fm-making-form ref="makingform" style="height: calc(100vh - 84px);" preview generate-code generate-json upload clearable > <template slot="action"> <el-button type="primary" icon="el-icon-upload" size="mini" @click="saveCode()">保存代碼</el-button> </template> </fm-making-form>
由於這段代碼是在自己定義的組件makingform.vue中處理的,那么獲取到JSON信息后,需要拋出一個事件來告訴外部即可。
saveCode() { // 保存代碼 const json = this.$refs.makingform.getJSON();// getHtml() // console.log(json) this.$emit('save', JSON.stringify(json)); // 觸發事件,返回內容 this.isShowForm = false }
在剛才的界面中,使用自定義的makingform組件代碼如下所示。
<makingform ref="makingform" @save="saveCode" />
當然這里保存的操作就是把新的JSON代碼存儲到界面的textarea組件上了,這樣就實現了我們動態表單界面結構JSON的更新了。
saveCode(json) { if (this.isAdd) { this.addForm.content = json } else if (this.isEdit) { this.editForm.content = json } },
當然,我們打開makingform組件的時候,如果已經有了JSON信息,那么也是需要加載它已有的界面結果的。
在主體調用界面上,我們打開設計界面的時候,就需要傳入對應的JSON數據。
showMaking() { if (this.isAdd) { this.$refs.makingform.show()// 顯示窗口 } else if (this.isEdit) { this.$refs.makingform.show(this.editForm.content)// 顯示窗口 } },
而在組件上,我們根據JSON賦值給設計器控件即可。
show(json) { // 顯示窗口並加載數據 this.isShowForm = true if (!this.isEmpty(json)) { // 表單結構 this.jsonData = JSON.parse(json) // console.log(this.jsonData) this.$nextTick(() => { this.$refs.makingform.setJSON(this.jsonData); }) } },
有了這些動態表單界面數據的准備,我們就可以在具體表單里面,整合這些設計的界面,從而實現動態表單的展示了。
為了比較直觀顯示我們對應設計的表單,我們也在列表中提供了一個預覽的界面,用於預覽生成的表單界面效果。
單擊預覽按鈕,可以查看具體設計的表單效果,表單的呈現是通過其中的fm-generate-form 來呈現效果的。
2、動態表單的數據存儲
這里根據上面的動態表單設計的界面,整合並存儲對應界面控件的值,從而實現了動態表單和動態表單數據的整合顯示了。
為了有效管理動態表單的數據和是否展示的處理,我們在業務表單的data屬性集合中增加了兩個變量,如下所示。
hasDynamicForm: false, // 是否有動態表單 dynamicFormJson: '', // 動態表單的JSON數據
這樣我們在業務表單列表界面呈現的時候,也同時獲取對應的動態界面結構JSON,如下代碼所示。
created() { this.getlist() // 獲取並顯示列表 // 處理動態表單 var param = { name: 'testuser' } dynamicForm.FindByName(param).then(data => { var result = data.result if (result && !this.isEmpty(result.content)) { this.dynamicFormJson = result.content // 表單數據 this.hasDynamicForm = true // 是否有 } }) },
這些屬性,可以在查看、編輯、新增界面中使用,為了獨立性考慮,我們添加一個選項卡用來顯示動態表單的設計,如果對應的記錄中存在了動態表單結構,就顯示,否則不顯示即可。
界面代碼如下所示。
其中動態表單數據主要存儲在extensionData字段里面的。
其中的generateform 組件,是我們自定義整合fm-generate-form 組件的,完整的自定義組件generateform代碼如下所示。
主要就是定義了兩個prop屬性,一個是json,用來存儲結構數據,一個是edit,用來存儲界面組件的JSON數據信息的。
<template> <div class="app-container"> <div class="fm-container"> <fm-generate-form ref="generateForm" :data="jsonData" :remote="remoteFuncs" :value="editData" /> </div> </div> </template> <script> import Vue from 'vue' import VueEditor from 'vue2-editor' Vue.use(VueEditor) import FormMaking from 'form-making' import 'form-making/dist/FormMaking.css' Vue.use(FormMaking) export default { props: { json: { type: String, default: '' }, edit: { type: String, default: '' } }, data() { return { jsonData: {}, editData: {}, remoteFuncs: {} } }, created() { this.show(this.json, this.edit) }, methods: { clear() { this.$nextTick(() => { this.$refs.generateForm.reset() }) }, show(json, edit) { // 顯示窗口並加載數據 // console.log(json) // console.log(edit) if (!this.isEmpty(json)) { // 表單結構 this.jsonData = JSON.parse(json) } if (!this.isEmpty(edit)) { // 表單結構 this.editData = JSON.parse(edit) } }, getData() { // 獲取動態表單數據並轉換JSON return this.$refs.generateForm.getData() } } } </script> <style lang="scss" scoped> .app-container,.fm-container{ height: calc(100vh - 84px); } </style> <style> #app .app-container { padding: 0 !important; } </style>
3、后端ABP框架的擴展數據處理
前面說到的顯示動態表單及其數據的內容,其中動態表單數據主要存儲在extensionData字段里面的。
這個需要我們后端提供數據存儲的處理,在設計表中增加一個ntext類型的字段ExtensionData,如下所示。
那樣ABP后端的Entity實體,和DTO數據對象里面,都添加這個字段信息了
/// <summary> /// 擴展JSON數據 /// </summary> public string ExtensionData { get; set; }
這樣ABP就可以通過不同的前端實現數據的存儲處理了。
為了方便讀者理解,我列出一下前面幾篇隨筆的連接,供參考:
循序漸進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前端的整合
使用代碼生成工具快速生成基於ABP框架的Vue+Element的前端界面
循序漸進VUE+Element 前端應用開發(20)--- 使用組件封裝簡化界面代碼
循序漸進VUE+Element 前端應用開發(21)--- 省市區縣聯動處理的組件使用
循序漸進VUE+Element 前端應用開發(22)--- 簡化main.js處理代碼,抽取過濾器、全局界面函數、組件注冊等處理邏輯到不同的文件中
循序漸進VUE+Element 前端應用開發(23)--- 基於ABP實現前后端的附件上傳,圖片或者附件展示管理
循序漸進VUE+Element 前端應用開發(24)--- 修改密碼的前端界面和ABP后端設置處理
循序漸進VUE+Element 前端應用開發(25)--- 各種界面組件的使用(1)
循序漸進VUE+Element 前端應用開發(26)--- 各種界面組件的使用(2)
循序漸進VUE+Element 前端應用開發(27)--- 數據表的動態表單設計和數據存儲
循序漸進VUE+Element 前端應用開發(28)--- 附件內容的管理
循序漸進VUE+Element 前端應用開發(29)--- 高級查詢條件的界面設計
部署基於.netcore5.0的ABP框架后台Api服務端,以及使用Nginx部署Vue+Element前端應用
循序漸進VUE+Element 前端應用開發(30)--- ABP后端和Vue+Element前端結合的分頁排序處理
循序漸進VUE+Element 前端應用開發(31)--- 系統的日志管理,包括登錄日志、接口訪問日志、實體變化歷史日志
循序漸進VUE+Element 前端應用開發(32)--- 手機短信動態碼登陸處理
循序漸進VUE+Element 前端應用開發(33)--- 郵件參數配置和模板郵件發送處理
使用Vue-TreeSelect組件實現公司-部門-人員級聯下拉列表的處理
使用Vue-TreeSelect組件的時候,用watch變量方式解決彈出編輯對話框界面無法觸發更新的問題