在我们一些系统里面,有时候会需要一些让用户自定义的数据信息,一般这些可以使用扩展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前端的整合

循序渐进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)--- 数据表的动态表单设计和数据存储

循序渐进VUE+Element 前端应用开发(27)--- 数据表的动态表单设计和数据存储的更多相关文章

  1. 循序渐进VUE+Element 前端应用开发(29)--- 高级查询条件的界面设计

    在系统模块中的业务列表展示里面,一般我们都会在列表中放置一些查询条件,如果是表字段不多,大多数情况下,放置的条件有十个八个就可以了,如果是字段很多,而这些条件信息也很关键的时候,就可能放置很多条件,但 ...

  2. 循序渐进VUE+Element 前端应用开发(28)--- 附件内容的管理

    在我们很多模块里面,都需要使用到一些诸如图片.Excel文件.PDF文件等附件的管理,一般我们倾向于把它独立为一个公用的附件管理模块,这样可以有效的统一管理附件的信息.本篇随笔介绍附件内容的管理,包括 ...

  3. 循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理

    在前面随笔<循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理>中介绍了在Vue + Element整合框架中,实现了动态菜单和动态路由的处理,从而可以根据 ...

  4. 循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理

    在我们一般开发的系统界面里面,列表页面是一个非常重要的综合展示界面,包括有条件查询.列表展示和分页处理,以及对每项列表内容可能进行的转义处理,本篇随笔介绍基于Vue +Element基础上实现表格列表 ...

  5. 循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用

    在我们开发BS页面的时候,往往需要了解常规界面组件的使用,小到最普通的单文本输入框.多文本框.下拉列表,以及按钮.图片展示.弹出对话框.表单处理.条码二维码等等,本篇随笔基于普通表格业务的展示录入的场 ...

  6. 循序渐进VUE+Element 前端应用开发(8)--- 树列表组件的使用

    在我前面随笔<循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用>里面曾经介绍过一些常规的界面组件的处理,主要介绍到单文本输入框.多文本框.下拉列 ...

  7. 循序渐进VUE+Element 前端应用开发(9)--- 界面语言国际化的处理

    我们开发的系统,一般可以不用考虑语言国际化的问题,大多数系统一般是给本国人使用的,而且直接使用中文开发界面会更加迅速 一些,不过框架最好能够支持国际化的处理,以便在需要的时候,可以花点时间来实现多语言 ...

  8. 循序渐进VUE+Element 前端应用开发(10)--- 基于vue-echarts处理各种图表展示

    在我们做应用系统的时候,往往都会涉及图表的展示,综合的图表展示能够给客户带来视觉的享受和数据直观体验,同时也是增强客户认同感的举措之一.基于图表的处理,我们一般往往都是利用对应第三方的图表组件,然后在 ...

  9. 循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理

    VUE+Element 前端是一个纯粹的前端处理,前面介绍了很多都是Vue+Element开发的基础,从本章随笔开始,就需要进入深水区了,需要结合ABP框架使用(如果不知道,请自行补习一下我的随笔:A ...

随机推荐

  1. mongodb安装及使用

    安装命令: sudo apt-get install mongodb 开始认证,创建用户: 编辑配置文件: sudo vim /etc/mongodb.conf 11行中的 bind_ip值 修改成为 ...

  2. Spring源码解析之基础应用(三)

    组合Java配置 在XML中,我们可以使用<import/>标签,在一个XML文件中引入另一个XML文件,在Java类中,我们同样可以在一个配置类中用@Import引入另一个配置类,被引入 ...

  3. .net 连接数据库实例

    web.config配置 <appSettings> <add key="ConnectionString" value="server=.;datab ...

  4. subprocess中命令为参数序列和字符串的区别

    参数args 参数args可以是一个参数序列,也可以是一个单独的字符串.参数序列通常是首选的,因为它允许模块处理参数的转义和引号(例如,允许文件名中有空格). 如果传递参数序列,默认情况下,程序执行序 ...

  5. MySQL历史

    MySQL历史 马云生气了 去IOE活动 1979年 研发一个引擎 1996年 发布MySQL1.0 1999年 瑞典注册AB公司 2003年 MySQL 5.0版本 提供试图.存储过程 具有了一些企 ...

  6. MVC联想查询绑定下拉框

    前言 在做搜索时,输入些内容时需要弹出下拉框给用户进行选择,极大的方便了用户,会给用户带来不一样的体验 Controller public ActionResult SSAC(string UserN ...

  7. IDEA安装IDEA阿里Java规范插件

    插件安装方式有两种: 1.通过在线方式安装,搜索后找到,点击Install安装即可: 2.去官网plugins下载对应插件离线包,地址:https://plugins.jetbrains.com/pl ...

  8. 万字长文深入理解java中的集合-附PDF下载

    目录 1. 前言 2. List 2.1 fail-safe fail-fast知多少 2.1.1 Fail-fast Iterator 2.1.2 Fail-fast 的原理 2.1.3 Fail- ...

  9. vue-router入门随笔

    下面整理根据官方文档以及自我理解整理,如有不足,请指教. 下面是来自一段官方的原话. Vue Router 是 Vue.js 官方的路由管理器.它和 Vue.js 的核心深度集成,让构建单页面应用变得 ...

  10. CodeForces 578E Walking!

    题意 略. 题解 好毒瘤啊,我最多就口胡第一问的样子吧. 第一问很显然(跟凤凰县探险队员一样显然),就是每次贪心选长度最大的满足条件的子序列,选不到就折返回来.所以折返的次数很明显就是选出子序列的个数 ...