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 相关文章推荐
JQuery学习笔录 简单的JQuery
Apr 09 Javascript
node.js应用后台守护进程管理器Forever安装和使用实例
Jun 01 Javascript
jquery实现简单的轮换出现效果实例
Jul 23 Javascript
AngularJS实现标签页的两种方式
Sep 05 Javascript
Vue 短信验证码组件开发详解
Feb 14 Javascript
微信小程序表单验证form提交错误提示效果
Jun 19 Javascript
对angularJs中2种自定义服务的实例讲解
Sep 30 Javascript
vue src动态加载请求获取图片的方法
Oct 17 Javascript
Webstorm2016使用技巧(SVN插件使用)
Oct 29 Javascript
vue 实现 rem 布局或vw 布局的方法
Nov 13 Javascript
JQuery常用选择器功能与用法实例分析
Dec 23 jQuery
js实现二级联动简单实例
Jan 11 Javascript
新手如何快速理解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
dede3.1分页文字采集过滤规则详说(图文教程)续四
2007/04/03 PHP
php下将图片以二进制存入mysql数据库中并显示的实现代码
2010/05/27 PHP
Mysql数据库操作类( 1127版,提供源码下载 )
2010/12/02 PHP
PHP获取文件相对路径的方法
2015/02/26 PHP
php隐藏实际地址的文件下载方法
2015/04/18 PHP
老版本PHP转义Json里的特殊字符的函数
2015/06/08 PHP
点击广告后才能获得下载地址
2006/10/26 Javascript
Stop SQL Server
2007/06/21 Javascript
基于Jquery的实现回车键Enter切换焦点
2010/09/14 Javascript
优化RequireJS项目的相关技巧总结
2015/07/01 Javascript
jQuery实现元素拖拽并cookie保存顺序的方法
2016/02/20 Javascript
AngularJS入门教程之AngularJS指令
2016/04/18 Javascript
JavaScript进阶练习及简单实例分析
2016/06/03 Javascript
jQuery模拟select实现下拉菜单功能
2016/06/20 Javascript
js中的关联数组与普通数组详解
2016/07/27 Javascript
vue实现裁切图片同时实现放大、缩小、旋转功能
2018/03/02 Javascript
JS实现带阴历的日历功能详解
2019/01/24 Javascript
微信小程序 如何获取网络状态
2019/07/26 Javascript
layui 选择列表,打勾,点击确定返回数据的例子
2019/09/02 Javascript
js与jquery获取input输入框中的值实例讲解
2020/02/27 jQuery
[01:12:44]VG vs Mineski Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
Python守护线程用法实例
2017/06/23 Python
pycharm 在windows上编辑代码用linux执行配置的方法
2018/10/27 Python
python实现的多任务版udp聊天器功能案例
2019/11/13 Python
Python关于反射的实例代码分享
2020/02/20 Python
Django操作session 的方法
2020/03/09 Python
keras Lambda自定义层实现数据的切片方式,Lambda传参数
2020/06/11 Python
CSS3实现类似翻书效果的过渡动画的示例代码
2019/09/06 HTML / CSS
CSS3 animation实现逐帧动画效果
2016/06/02 HTML / CSS
俄罗斯最大的在线手表商店:Bestwatch.ru
2020/01/11 全球购物
烹饪自我鉴定
2014/03/01 职场文书
乡镇三项教育实施方案
2014/03/30 职场文书
民事诉讼代理授权委托书
2014/10/11 职场文书
2015年“我们的节日·重阳节”活动总结
2015/07/29 职场文书
2016清明节森林防火广播稿
2015/12/17 职场文书
python实现web邮箱扫描的示例(附源码)
2021/03/30 Python