iView Table 当有fixed列时会将每一列的dom复制一份,可能导致ref重名,验证无效等问题

背景

image

注意上图中那个td元素是固定列中的一个单元格,其被设为不可见,见下图:
image

下面这个图.ivu-table-fixed .ivu-table-fixed-body 下面的td 才是真正页面上显示出来的固定列单元格的DOM
image

了解Form表单组件的应该知道,当表单项验证失败时,表单项上的错误信息其实是表单项元素上多了一个ivu-form-item-error类
image

问题

我项目中有类似如下的代码。奇怪的现象是,当手动去触发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" >



iView官方文档

posted @ 2024-10-15 16:41  johnjackson  阅读(42)  评论(0编辑  收藏  举报