iView Table 当有fixed列时会将每一列的dom复制一份,可能导致ref重名,验证无效等问题
背景
注意上图中那个td元素是固定列中的一个单元格,其被设为不可见,见下图:
下面这个图.ivu-table-fixed .ivu-table-fixed-body 下面的td 才是真正页面上显示出来的固定列单元格的DOM
了解Form表单组件的应该知道,当表单项验证失败时,表单项上的错误信息其实是表单项元素上多了一个ivu-form-item-error类
问题
我项目中有类似如下的代码。奇怪的现象是,当手动去触发input框的blur事件时验证行为正常。
但是,当初始进入页面时,如果直接调用
this.$refs['myFormRef' + index].validate((valid)=>{}),
会发现,验证结果为false(因为文本框值为空),文本框却没有验证失败的样式(文本框红色边框,下方显示‘必填’。
<Table ...>
<!-- 某一列的单元格定义 -->
<template slot="..." slot-scope="params">
<i-form :ref="'myFormRef' + params.index" model="params.row" >
<form-item prop="..." :rules="[{required: true, message: '必填', trigger: 'blur'}]">
<input v-model="..." />
</form-item>
</i-form>
</template>
<Table>
在开发者工具中查看.ivu-form-item元素,确实没有ivu-form-item-error类。
原因
其实这个问题是因为iView Table组件当有列设为'fixed'时,组件渲染时就会把所有的普通列都复制一份放到table-fixed相应的td中,以起到占位的效果。
但是这会带来一些问题,比如,我这里遇到的验证失败不显示结果的问题。其本根据原因是Table组件在复制单元格的元素时,把其ref也一并复制了,这就导致页面上存在两个相同的ref。
当在js中调用this.$refs.myFormRef时,其指向的并不是可见的那个元素,而是在fixed table中那个不可见的。
可以通过console.log(this.$refs.myFormRef)验证。
解决方法
// js、vue
data() {
return {
// ...
refCounter: {}, // 用于存储每个 ref 名称的计数
}
},
methods: {
// ...
genRef(baseRefName) {
// 如果 ref 名称不存在于计数对象中,初始化为 0
if (!this.refCounter[baseRefName]) {
this.refCounter[baseRefName] = 0;
}
// 增加计数并返回新的 ref 名称
this.refCounter[baseRefName] += 1;
console.log(`${baseRefName}${this.refCounter[baseRefName]}`);
return `${baseRefName}${this.refCounter[baseRefName]}`; // 生成新的 ref 名称
},
save() {
this.$refs.['myFormRef' + '1'].validate(valid => {});
}
}
html:
<i-form :ref="genRef('myFormRef' + params.index)" model="params.row" >
喜欢的话,请点赞,转发、收藏、评论,谢谢!