牵扯三方: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"
,让内容自适应。
这时,控制台就会出现一个错误,虽然对使用没有影响,但是一看红色就给人感觉是出错了:
后面解决方法是 将 v-show="type === 1"
修改为 v-if="type === 1"
然后就影响到表单验证了。。。
出现的bug
- 页面一打开,表单验证的 提示消息 就出现
- 有些验证相当于没有,会直接跳过验证,调用接口,这是调用接口就会出错
- 即便填入相关的信息,验证提示也不会消失
其他bug显示,跟这些类似,表单验证不能正常使用
出现原因
- 使用v-if: element在对 form 表单中带有prop属性的子组件进行校验规则绑定时,是在 Vue 声明周期
mounted
完成的。而v-if用来切换的元素是会被销毁的,导致了v-if内的表单项,由于在 mounted 时期没有进行渲染,所以规则也没有绑定上,因此初始化时不符合显示条件的不会生成规则,导致后面切换条件,显示的输入框的校验也不会生效/消失。 - 使用v-show: 初始化时会生成所有的规则,即使隐藏了也会进行校验
一个是无法正常使用,一个是隐藏了也会校验,多耗点性能
解决以及注意事项
- 将 label-width 改回固定宽度,数值跟之前相比,大点;然后,
v-if
改回v-show
- 给设置 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,同时使用时,会有冲突