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实现相同内容合并单元格的代码
Jan 12 Javascript
jquery图片放大功能简单实现
Aug 01 Javascript
JS实现图片翻书效果示例代码
Sep 09 Javascript
JavaScript简单实现鼠标拖动选择功能
Mar 06 Javascript
JS兼容浏览器的导出Excel(CSV)文件的方法
May 03 Javascript
jquery实现带缩略图的可定制高度画廊效果(5种)
Aug 28 Javascript
js图片卷帘门导航菜单特效代码分享
Sep 10 Javascript
用canvas 实现个图片三角化(LOW POLY)效果
Feb 18 Javascript
Javascript 闭包详解及实例代码
Nov 30 Javascript
什么是Vue.js框架 为什么选择它?
Oct 17 Javascript
ReactNative实现Toast的示例
Dec 31 Javascript
10个经典的网页鼠标特效代码
Jan 09 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
海贼王:最美的悬赏令!
2020/03/02 日漫
php使用Jpgraph绘制复杂X-Y坐标图的方法
2015/06/10 PHP
phpstudy2018升级MySQL5.5为5.7教程(图文)
2018/10/24 PHP
解决Laravel5.x的php artisan migrate数据库迁移创建操作报错SQLSTATE[42000]
2020/04/06 PHP
picChange 图片切换特效的函数代码
2010/05/06 Javascript
javascript+xml实现简单图片轮换(只支持IE)
2012/12/23 Javascript
js导航菜单(自写)简单大方
2013/03/28 Javascript
JS实现仿京东淘宝竖排二级导航
2014/12/08 Javascript
JavaScript常用小技巧小结
2014/12/29 Javascript
jQuery中借助deferred来请求及判断AJAX加载的实例讲解
2016/05/24 Javascript
AngularJS基础 ng-readonly 指令简单示例
2016/08/02 Javascript
JS识别浏览器类型(电脑浏览器和手机浏览器)
2016/11/18 Javascript
js 定位到某个锚点的方法
2016/11/19 Javascript
js实现交通灯效果
2017/01/13 Javascript
微信小程序 页面之间传参实例详解
2017/01/13 Javascript
基于AngularJS实现表单验证功能
2017/07/28 Javascript
微信小程序 动画的简单实例
2017/10/12 Javascript
基于vue2.0实现简单轮播图
2017/11/27 Javascript
AngularJS监听ng-repeat渲染完成的两种方法
2018/01/16 Javascript
Vue实现6位数密码效果
2018/08/18 Javascript
jQuery Migrate 插件用法实例详解
2019/05/22 jQuery
vue实现瀑布流组件滑动加载更多
2020/03/10 Javascript
javascript实现点击产生随机图形
2021/01/25 Javascript
Python实现获取某天是某个月中的第几周
2015/02/11 Python
Python的字典和列表的使用中一些需要注意的地方
2015/04/24 Python
利用Python如何生成随机密码
2016/04/20 Python
Python实现string字符串连接的方法总结【8种方式】
2018/07/06 Python
详解CSS3浏览器兼容
2016/12/14 HTML / CSS
phpquery中文手册
2021/03/18 PHP
MIKI HOUSE美国官方网上商店:日本领先的婴儿和儿童高级时装品牌
2020/06/21 全球购物
经理职责范文
2013/11/08 职场文书
淘宝好评语大全
2014/05/05 职场文书
地理科学专业自荐信
2014/09/01 职场文书
国家税务局干部作风整顿整改措施
2014/09/18 职场文书
MySQL中VARCHAR与CHAR格式数据的区别
2021/05/26 MySQL
MySQL 四种连接和多表查询详解
2021/07/16 MySQL