循序漸進VUE+Element 前端應用開發(27)--- 資料表的動態表單設計和資料儲存
在我們一些系統裡面,有時候會需要一些讓使用者自定義的資料資訊,一般這些可以使用擴充套件JSON進行儲存,不過每個業務表的顯示專案可能不一樣,因此需要根據不同的表單進行設計,然後進行對應的資料儲存。本篇隨筆結合基於Vue+Element實現動態表單的設計、資料錄入儲存的相關操作。
1、動態表單的設計
動態表單的設計一般是基於某個能夠動態設計介面的方式實現的,介面上定義對應的說明以及錄入資料的方式,如標籤後面加上文字,或者多文字等方式。由於我們後臺是強型別的資料實體,後端一般不採用動態修改資料庫欄位的方式構建,而是採用擴充套件JSON結構的方式來定義整個動態表單的結構,動態擴充套件的JSON結構比較彈性,不用可以隨時移除,也可隨時增加,非常方便,這是一樣常見的處理資料結構方式。
表單設計器有很多元件可以使用
- https://github.com/GavinZhuLei/vue-form-making
- https://github.com/JakHuang/form-generator
不過我傾向於使用前者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前端的整合
循序漸進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)
ABP框架中一對多,多對多關係的處理以及功能介面的處理(1)
電商商品資料庫的設計和功能介面的處理
ABP框架中一對多,多對多關係的處理以及功能介面的處理(2)
循序漸進VUE+Element 前端應用開發(27)--- 資料表的動態表單設計和資料儲存