参考:
- 深入了解Element Form表单动态验证问题 转载
- vue elementUI组件表单动态验证失效的问题与解决办法
在别人的代码上开发新功能时,发现动态表单的校验功能突然出现问题:
重构前,只有两步,通过type来判断当前显示内容
<el-form>
<div v-if="type"> 第一步
<el-form-item></el-form-item>
...
<div>
<div v-if="type == false"> 第二步
<div>
<el-form-item></el-form-item>
...
</div>
...
<div>
</el-form>
重构后,有4步
<el-form>
<div v-if="step === 1"> 第一步
<el-form-item></el-form-item>
...
<div>
<div v-if="step === 2"> 第二步
<el-form-item></el-form-item>
...
<div>
<div v-if="step === 3"> 第3步
<el-form-item></el-form-item>
...
<div>
<div v-if="step === 4"> 第4步
<el-form-item></el-form-item>
...
<div>
</el-form>
在测试时发现,第一步校验没有问题,一旦进入第二步,就只触发了部分一个或者两个校验。
通过对比重构前的代码,发现和之前的一样,在el-form-item外套一层div就可以了
<el-form>
<div v-if="step === 1"> 第一步
<el-form-item></el-form-item>
...
<div>
<div v-if="step === 2"> 第二步
<div>
<el-form-item></el-form-item>
...
</div>
<div>
想知道发生了什么导致这种情况,于是去看el-form的源码,发现校验的触发数量,与其属性fields有关系,如图
左边元素有6个, 而右边fields只有1个
所以在触发校验时,只有一个,如下
那么现在的问题就是:fields的数据是如何变化的?在源码中找到如下位置,根据子组件的创建销毁来修改fields
el-form:
el-form-item:
到了这里,多半就可以确定的是元素更新的问题了,在el-form-item外套一层div,进入第二步后元素布局就与第一步不同,从而刷新了所有元素。进而fields中的数据也就齐全了。
后面我又试了下,如果给第一步的el-form-item套div,第二步不套也可以解决。
但是,如果同时套上div,那么相对来说el-form中el-form-item的结构就没有发生变化,就产生了同样的问题,因此套div的方式并不可取。
为了给 Vue 一个提示,以便它可以跟踪每个节点的标识,从而重用和重新排序现有的元素,你需要为每个元素对应的块提供一个唯一的 key
现在的方法是:给每个v-if设置key
<el-form>
<div v-if="step === 1" key="1"> 第一步
<el-form-item></el-form-item>
...
<div>
<div v-if="step === 2" key="2"> 第二步
<el-form-item></el-form-item>
...
<div>
<div v-if="step === 3" key="3"> 第3步
<el-form-item></el-form-item>
...
<div>
<div v-if="step === 4" key="4"> 第4步
<el-form-item></el-form-item>
...
<div>
</el-form>