el-form与v-if冲突,导致表单校验出问题

552 阅读2分钟

牵扯三方:v-if/v-show、el-form、label-width: auto/ 数值px

最近,刚做完的页面拿去测试,结果一下子出现六个bug。。。

还好是同一个bug所测出的同一类问题,但是则测试眼里那就是6个bug

场景复现

引入elementUI中的form表单:

<!-- 刚好特殊情况,有多个表单,因此加上了 v-show="条件判断" -->
<div v-show="type === 1">
    <el-form
		ref="form"
    	:rules="rules"
    	label-width="150px"
        <!-- 后面提出将label-width="固定值" 改为 label-width="auto" -->
	>
    	<el-form-item prop="noteName">
            <el-input></el-input>
        </el-form-item>
	</el-form>
</div>
data() {
    return {
        // 表单规则
        rules: {
            noteName: [{
                required: true,
                message: '请输入正确的姓名',
                trigger: ['change', 'select']
            }]
        }
    }
}

当用户在输入框中输入的值,超出输入框的宽度 label-width="150px",那么表单的内容就会往下掉,于是改为将固定值改为

label-width="auto",让内容自适应。

这时,控制台就会出现一个错误,虽然对使用没有影响,但是一看红色就给人感觉是出错了:

el-form与v-if报错截图.png

后面解决方法是 将 v-show="type === 1" 修改为 v-if="type === 1"

然后就影响到表单验证了。。。

出现的bug

  • 页面一打开,表单验证的 提示消息 就出现

image.png

  • 有些验证相当于没有,会直接跳过验证,调用接口,这是调用接口就会出错
  • 即便填入相关的信息,验证提示也不会消失

image.png

其他bug显示,跟这些类似,表单验证不能正常使用

出现原因

v-if和v-show的区别

  1. 使用v-if: element在对 form 表单中带有prop属性的子组件进行校验规则绑定时,是在 Vue 声明周期 mounted 完成的。而v-if用来切换的元素是会被销毁的,导致了v-if内的表单项,由于在 mounted 时期没有进行渲染,所以规则也没有绑定上,因此初始化时不符合显示条件的不会生成规则,导致后面切换条件,显示的输入框的校验也不会生效/消失
  2. 使用v-show: 初始化时会生成所有的规则,即使隐藏了也会进行校验

一个是无法正常使用,一个是隐藏了也会校验,多耗点性能

解决以及注意事项

  1. 将 label-width 改回固定宽度,数值跟之前相比,大点;然后, v-if改回v-show
  2. 给设置 v-if 的元素加上key值(没试过)
<div v-if="type === 1">
    <el-form
		ref="form"
    	:rules="rules"
        key="title"
    	label-width="150px"
	>
    	<el-form-item prop="noteName">
            <el-input></el-input>
        </el-form-item>
	</el-form>
</div>

原理:在v-if切换标签时,多个相同的标签会被渲染,如果不添加key来区分则会出现复用的情况。同理:v-for渲染的标签也要加key来区分。而原本这些标签每一个都是独立的,所以需要添加key来区分。

注意事项:

  • el-form表单的验证 与 v-if ,同时使用时,会有表单验证失败问题
  • label-width = "auto" 与 v-if,同时使用时,会有冲突