el-form resetFields无效和validate无效
苏格拉没有底v 人气:0问题导入
在使用 el-form
过程中,尤其是表单验证这一块,官方提供的 reserFields
方法以及验证方面存在一些坑,在此记录一下,给大家提供可能的解决办法。
简单实例
1、官方案例
先来看看官方提供的案例,对应的官网 表单验证
对应的代码
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <el-form-item label="活动名称" prop="name"> <el-input v-model="ruleForm.name"></el-input> </el-form-item> <el-form-item label="活动区域" prop="region"> <el-select v-model="ruleForm.region" placeholder="请选择活动区域"> <el-option label="区域一" value="shanghai"></el-option> <el-option label="区域二" value="beijing"></el-option> </el-select> </el-form-item> <el-form-item label="活动时间" required> <el-col :span="11"> <el-form-item prop="date1"> <el-date-picker type="date" placeholder="选择日期" v-model="ruleForm.date1" style="width: 100%;"></el-date-picker> </el-form-item> </el-col> <el-col class="line" :span="2">-</el-col> <el-col :span="11"> <el-form-item prop="date2"> <el-time-picker placeholder="选择时间" v-model="ruleForm.date2" style="width: 100%;"></el-time-picker> </el-form-item> </el-col> </el-form-item> <el-form-item label="即时配送" prop="delivery"> <el-switch v-model="ruleForm.delivery"></el-switch> </el-form-item> <el-form-item label="活动性质" prop="type"> <el-checkbox-group v-model="ruleForm.type"> <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox> <el-checkbox label="地推活动" name="type"></el-checkbox> <el-checkbox label="线下主题活动" name="type"></el-checkbox> <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox> </el-checkbox-group> </el-form-item> <el-form-item label="特殊资源" prop="resource"> <el-radio-group v-model="ruleForm.resource"> <el-radio label="线上品牌商赞助"></el-radio> <el-radio label="线下场地免费"></el-radio> </el-radio-group> </el-form-item> <el-form-item label="活动形式" prop="desc"> <el-input type="textarea" v-model="ruleForm.desc"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button> <el-button @click="resetForm('ruleForm')">重置</el-button> </el-form-item> </el-form> <script> export default { data() { return { ruleForm: { name: '', region: '', date1: '', date2: '', delivery: false, type: [], resource: '', desc: '' }, rules: { name: [ { required: true, message: '请输入活动名称', trigger: 'blur' }, { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' } ], region: [ { required: true, message: '请选择活动区域', trigger: 'change' } ], date1: [ { type: 'date', required: true, message: '请选择日期', trigger: 'change' } ], date2: [ { type: 'date', required: true, message: '请选择时间', trigger: 'change' } ], type: [ { type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' } ], resource: [ { required: true, message: '请选择活动资源', trigger: 'change' } ], desc: [ { required: true, message: '请填写活动形式', trigger: 'blur' } ] } }; }, methods: { submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); } } } </script>
对应的字段含义,在官网上都有详细的解释,那么如果类似的表单重置 resetFields
时候无法成功,那么可能的原因有哪些呢?(以下皆由个人实践得出,具体原因有些不太懂,欢迎解释补充)
resetFields 失败可能原因
1:
el-form
中使用 v-model="ruleForm"
代替了:model="ruleForm"
,正确的应为后者。
2:
el-form-item
中的 prop
属性设置错误,官网给出了解释。即 prop=a
, v-model=Form.a
,Js中表单数据字段Form:{ a:'', b: [] }
,需要一一对应,不能出现差错。
3:
<el-button @click="resetForm('ruleForm')">重置</el-button>
resetForm(formName)的参数一定要和 el-form
中 ref ="formName"
一致。
2、个人案例
项目开发过程中,通常 el-form
都是嵌套在el-dialog
中。在表格页面中,点击添加或者修改按钮,弹出同一个表单,因为两个操作都是类似的组件,不同的组件可以用 v-if
屏蔽掉,这也是大多数开发中公用组件的一个体现。
举个个例:
通过添加按钮和编辑按钮都能够打开这个dialog。
EditRole.vue
<template> <div style="text-align: left;"> <el-button class="add-button" type="success" @click="dialogFormVisible = true">添加角色</el-button> <el-dialog :title="title" :visible.sync="dialogFormVisible" @close="clear" > <el-form :model="form" ref="roleForm" :rules="rules"> <el-form-item label="角色名称" :label-width="formLabelWidth" prop="name"> <el-input v-model="form.name" autocomplete="off" placeholder="请输入新角色英文名称"></el-input> </el-form-item> <el-row> <el-col :span="16"> <el-form-item label="中文名称" :label-width="formLabelWidth" prop="nameZh"> <el-input v-model="form.nameZh" autocomplete="off" placeholder="请输入中文名称"></el-input> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="是否可用" :label-width="formLabelWidth" prop="enabled"> <el-switch v-model="form.enabled" :active-value="1" :inactive-value="0" active-color="#13ce66" inactive-color="#ff4949"> </el-switch> </el-form-item> </el-col> </el-row> <el-form-item label="功能简述" :label-width="formLabelWidth" prop="description"> <el-input v-model="form.description" autocomplete="off" type="textarea" :autosize="{ minRows: 2, maxRows: 4}" placeholder="请输入角色功能简述"></el-input> </el-form-item> <el-form-item prop="id" style="height: 0"> <el-input type="hidden" v-model="form.roleId" autocomplete="off"></el-input> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button @click="dialogFormVisible = false">取 消</el-button> <el-button type="info" @click="resetForm('form')">重置</el-button> <el-button type="primary" @click="submitForm('roleForm')">确 定</el-button> </div> </el-dialog> </div> </template> <script> export default { name: "EditRole", data () { return { form: { roleId: '', name: '', nameZh: '', enabled: 1, description: '', }, // 表单验证规则 rules: { name: [ { required: true, message: '请输入新角色英文名称', trigger: 'blur' }, ], nameZh: [ { required: true, message: '请输入角色中文名称', trigger: 'blur' }, ], description: [ { required: true, message: '请赋予角色简要的功能描述', trigger: 'blur' } ], }, dialogFormVisible: false, formLabelWidth: '120px', isShow: true, //是否显示父级菜单,添加的时候显示,修改的时候不让修改父级菜单。 title: '添加角色', } }, methods: { clear () { if (this.form.id !== '') { // 不为空,那么就是修改操作 this.isShow = false; this.title = '修改角色' } // 关闭弹框后清空数据, this.resetForm('roleForm') this.isShow = true; this.title = '添加角色' }, resetForm(formName) { // 重置表格内容 this.$refs[formName].resetFields(); }, submitForm (formName) { this.$refs[formName].validate((valid) => { if (valid) { ... }else { this.$notify({ type: 'error', message: '数据未填写完整,请仔细核对!' }) return false; } }) }, } } </script> <style scoped> .add-button { margin: 18px 0 0 10px; } </style>
resetFields失效及解决办法
先添加后编辑
一般打开这个页面后,我们测试数据的时候,都是先点击添加按钮,关闭dialog后,再点击编辑按钮。
此时你使用this.$refs[formName].resetFields();
是能够将表单重置为空的,因为初始化的时候,本来form数据就是空的。
先编辑后添加
但是若你先点击编辑按钮,通过父组件传递了 本行数据
到 el-dialog 的 el-form
时,退出后再点击添加按钮,此时会发现数据被污染,表单竟然不是空的,而是出现了刚才编辑那行的数据。图示:
关闭弹窗时,我们设置了clear函数,clear函数为关闭dialog执行的函数。其中调用了resetForm
函数,即利用this.$refs[formName].resetFields()
来希望重置数据。但是再点击添加按钮时,数据并没有清除。
这个现象的原因是因为dialog是懒加载的,通过表格中的编辑按钮打开dialog时,传过来了父组件行数据
。即初始化时数据并不是空的,而resetFields()
函数重置时,初始化的值是啥就是啥
。
了解本质后,那么解决这个问题就简单了,我们关闭弹出时,不使用resetFields()
函数不就行了。而是这样:
resetForm(formName) { console.log("谁要重置数据啊?" + formName) // 重置表格内容 this.form= { roleId: '', name: '', nameZh: '', enabled: 1, description: '', } },
改动后结果:
相当于编辑退出后,将form表单初始化为空,这样就无法出现污染了。但是这样也有个问题,重置数据后,无法移除校验效果。好在官方给了我们方法,只需要添加一行。
resetForm(formName) { console.log("谁要重置数据啊?" + formName) // 重置表格内容 this.form= { roleId: '', name: '', nameZh: '', enabled: 1, description: '', }, // 不使用resetFields后,重置时无法移除校验效果,使用以下函数移除 this.$refs[formName].clearValidate(); },
validate失效及解决办法
当使用表单验证的时候,如果正常的验证都无误,提交时,我们通过以下代码来判断是否验证成功。
submitForm (formName) { this.$refs[formName].validate((valid) => { if (valid) { ... }else { this.$notify({ type: 'error', message: '数据未填写完整,请仔细核对!' }) return false; } }) },
但是使用自定义验证规则是,注意规则中回调函数callback()
一定要写,官方文档也写的十分清楚。否则 if(valid)
条件无法判断,而且它是没有报错的。
如自定义邮箱校验的时候:
data() { const validateEmail = (rule, value, callback) => { let regEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/; if (!regEmail.test(this.form.email)) { return callback(new Error("邮箱格式不正确")); // 有一个if 就要 一个 callback } return callback(); // 返回一个回调函数给验证,是表单validate生效 }; return { // 表单数据 form: { user_id: '', ... email: '', }, // 表单验证规则 rules: { ... email: [ { required: true, message: '请输入真实邮箱地址,方便找回密码', validator: validateEmail, trigger: 'blur' }, ], }, } },
callback()
回调函数必须要被调用。
这是目前碰到的表单问题,大家有什么好的解决方案或者新问题,欢迎在评论区留言,帮助大家解决问题!
3、model is required for validate to work!
2021/4/21
今天给表的表单添加验证规则的时候,el-form-item
都配置好了prop
属性,但是无效,F12后给出一个警告
然后回去看el-form
时候,才发现 v-model =
没有改成 :model
,造成错误,在此更新一下。
结尾
加载全部内容