vue+elementUI 复杂表单的验证、数据提交方案问题


Posted in Javascript onJune 24, 2019

当我们在做后台管理系统时,经常会遇到非常复杂的表单:

  • 表单项非常多
  • 在各种表单类型下,显示不同的表单项
  • 在某些条件下,某些表单项会关闭验证
  • 每个表单项还会有其他自定义逻辑,比如 输入框可以插入模板变量、输入字符数量显示、图片上传并显示、富文本 。。。
  • 在这种错综复杂的情况下,完成表单的验证和提交
  • 可以查看具体例子:例子中省略了很多琐碎的功能,只保留整体的复杂表单框架,用于展示解决方案

方案1: 在一个 vue 文件中

所有的表单项显示隐藏、验证、数据获取、提交、自定义等逻辑放在一起

v-if/v-show
elementui

缺点

  • 还是乱
  • 一个 vue 文件,轻轻松松上 2000 行
  • 在我尝试加入一种新的表单类型时,我发现我已经无。从。下。手。

方案2:分离组件

其实很容易想到 根据不同的表单类型,分离出多个相应类型的子表单 。但我在实践时还是遇到了很多问题: 父子表单验证、整体提交数据的获取 等等,并总结出一套解决方案:

1. 子组件

所有的子组件中都需要包含两个方法 validate 、 getData 供父组件调用。

(1) validate 方法

用于验证本身组件的表单项,并返回一个 promise 对象

vaildate() {
 // 返回`elementUI`表单验证的结果(为`promise`对象)
 return this.$refs["ruleForm"].validate();
},
   

(2) getData 方法

提供子组件中的数据

getData() {
 // 返回子组件的form
 return this.ruleForm;
},

2. 父组件

(1)策略模式

使用策略模式存储并获取 子表单的 ref (用于获取子表单的方法)和 提交函数 。省略了大量的 if-else 判断。

data:{
 // type和ref名称的映射
 typeRefMap: {
 1: "message",
 2: "mail",
 3: "apppush"
 },
 // type和提交函数的映射。不同类型,接口可能不同
 typeSubmitMap: {
 1: data => alert(`短信模板创建成功${JSON.stringify(data)}`),
 2: data => alert(`邮件模板创建成功${JSON.stringify(data)}`),
 3: data => alert(`push模板创建成功${JSON.stringify(data)}`)
 },
}

(2) submit 方法

用于父子组件表单验证、获取整体数据、调用当前类型提交函数提交数据

因为 elementUI 表单验证的 validate 方法可以返回 promise 结果 ,可以利用 promise 的特性来处理父子表单的验证。 比如 then 函数可以返回另一个 promise 对象 、 catch 可以获取它以上所有 then 的 reject 、 Promise.all 。

父表单验证通过才会验证子表单,存在先后顺序

// 父表单验证通过才会验证子表单,存在先后顺序
submitForm() {
 const templateType = this.typeRefMap[this.indexForm.type];
 this.$refs["indexForm"]
 .validate()
 .then(res => {
 // 父表单验证成功后,验证子表单
 return this.$refs[templateType].vaildate();
 })
 .then(res => {
 // 全部验证通过
 // 获取整体数据
 const reqData = {
 // 获取子组件数据
 ...this.$refs[templateType].getData(),
 ...this.indexForm
 };
 // 获取当前表单类型的提交函数,并提交
 this.typeSubmitMap[this.indexForm.type](reqData);
 })
 .catch(err => {
 console.log(err);
 });
},

父表单,子表单一起验证

submitForm1() {
 const templateType = this.typeRefMap[this.indexForm.type];
 const validate1 = this.$refs["indexForm"].validate();
 const validate2 = this.$refs[templateType].vaildate();
 // 父子表单一起验证
 Promise.all([validate1, validate2])
 .then(res => {
 // 都通过时,发送请求
 const reqData = {
 ...this.$refs[templateType].getData(),
 ...this.indexForm
 };
 this.typeSubmitMap[this.indexForm.type](reqData);
 })
 .catch(err => {
 console.log(err);
 });
},

查看在线项目,项目github和组件代码

总结

以上所述是小编给大家介绍的vue+elementUI 复杂表单的验证、数据提交方案问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
JavaScript OOP类与继承
Nov 15 Javascript
Extjs中TabPane如何嵌套在其他网页中实现思路及代码
Jan 27 Javascript
JavaScript解析URL参数示例代码
Aug 12 Javascript
基于编写jQuery的无缝滚动插件
Aug 02 Javascript
基于jquery编写的放大镜插件
Mar 23 Javascript
jQuery实现的可编辑表格完整实例
Jun 20 Javascript
Vue组件模板形式实现对象数组数据循环为树形结构(实例代码)
Jul 31 Javascript
JS运动改变单物体透明度的方法分析
Jan 23 Javascript
vue项目每30秒刷新1次接口的实现方法
Dec 04 Javascript
使用纯前端JavaScript实现Excel导入导出方法过程详解
Aug 07 Javascript
vue任意关系组件通信与跨组件监听状态vue-communication
Oct 18 Javascript
如何管理Vue中的缓存页面
Feb 06 Vue.js
新手如何快速理解js异步编程
Jun 24 #Javascript
简单了解小程序+node梳理登陆流程
Jun 24 #Javascript
JS数组扁平化(flat)方法总结详解
Jun 24 #Javascript
深入了解query和params的使用区别
Jun 24 #Javascript
如何使用JavaScript实现栈与队列
Jun 24 #Javascript
简单了解JavaScript中的执行上下文和堆栈
Jun 24 #Javascript
一次让你了解全部JavaScript的作用域
Jun 24 #Javascript
You might like
来自PHP.NET的入门教程
2006/10/09 PHP
laravel项目利用twemproxy部署redis集群的完整步骤
2018/05/11 PHP
Yii框架getter与setter方法功能与用法分析
2019/10/22 PHP
PHP终止脚本运行三种实现方法详解
2020/09/01 PHP
js仿百度有啊通栏展示效果实现代码
2013/05/28 Javascript
JavaScript实现的GBK、UTF8字符串实际长度计算函数
2014/08/27 Javascript
JavaScript中switch判断容易犯错的一个细节
2014/08/27 Javascript
浅谈javascript原型链与继承
2015/07/13 Javascript
jquery实现可自动判断位置的弹出层效果代码
2015/10/12 Javascript
Angularjs中UI Router全攻略
2016/01/29 Javascript
jQuery实现下拉加载功能实例代码
2016/04/01 Javascript
jQuery bt气泡实现悬停显示及移开隐藏功能的方法
2016/07/12 Javascript
Vue.js系列之vue-router(上)(3)
2017/01/03 Javascript
详解HTTPS 的原理和 NodeJS 的实现
2017/07/04 NodeJs
vue百度地图 + 定位的详解
2019/05/13 Javascript
vue项目中使用eslint+prettier规范与检查代码的方法
2020/01/16 Javascript
[10:18]2018DOTA2国际邀请赛寻真——找回自信的TNCPredator
2018/08/13 DOTA
[44:04]OG vs Mineski 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python循环语句中else的用法总结
2016/09/11 Python
Python cookbook(数据结构与算法)同时对数据做转换和换算处理操作示例
2018/03/23 Python
python调用摄像头显示图像的实例
2018/08/03 Python
利用Python将数值型特征进行离散化操作的方法
2018/11/06 Python
python实现鸢尾花三种聚类算法(K-means,AGNES,DBScan)
2019/06/27 Python
Python实现bilibili时间长度查询的示例代码
2020/01/14 Python
彻底搞懂 python 中文乱码问题(深入分析)
2020/02/28 Python
django 扩展user用户字段inlines方式
2020/03/30 Python
python如何建立全零数组
2020/07/19 Python
馥绿德雅美国官方网站:Rene Furterer头皮护理专家
2019/05/01 全球购物
卡骆驰英国官网:Crocs英国
2019/08/22 全球购物
Made in Design英国:设计家具、照明、家庭装饰和花园家具
2019/09/24 全球购物
英国奢侈品在线精品店:Hervia
2020/09/03 全球购物
应届硕士毕业生自荐信
2014/05/26 职场文书
师范大学生求职信
2014/06/13 职场文书
反腐倡廉标语
2014/06/24 职场文书
质量负责人岗位职责
2015/02/15 职场文书
护士业务学习心得体会
2016/01/25 职场文书