目录

1、问题背景:

2、问题描述:

3、 解决过程:

4、解决方法:

5、参考文章:


1、问题背景

我做了一个自定义组件,然后监听组件产生的数据作为form的值,表单大致结构如下:

<el-form-item :label="v.tagName" v-for="(v,k) in tags" :key="k" :prop="v.id+''">
          <el-tag style="margin: auto 3px" v-for="(item,index) in checkedMap[v.id]['objList']" :key="index"
                  size="medium" closable>
            {{ item.label }}
          </el-tag>
          <el-button icon="el-icon-plus" size="mini"
                     @click="openTagTree(v.id,v,checkedMap[v.id]['list'])"></el-button>
        </el-form-item>

这是表单的其中一个item,也是出问题的item。上述代码中可见我是将一个tag对象的Id转换为string作为prop,但是在item中却没有使用v-model来监听表单值的变化,而是通过下图中的“+”按钮调用其他组件来完成表单赋值。

2、问题描述:

如下图所示,由其他组件修改表单数据之后,验证器对表单进行验证时,并没有正确的给出验证结果,其机构项Item明明已有数据,但是验证器依旧给出了该项为空的提示。

下图中可以看到表单数据中(右侧标黄处)110项已有了数据,该项即是前面的被修改项,但是验证器依旧认为该项数据为空。 

3、 解决过程:

我猜测是因为Vue的数据变更监听问题,因为我在代码中多处使用了如下方式为表单进行赋值,在Vue中直接使用这种索引市赋值方法会造成Vue无法监听data中的数据变化,所以造成验证器无法认为该项Item还未被修改,最后导致了问题发生。

this.form['xxx']=['xxx']

4、解决方法:

在Vue中如果需要针对多层结构的对象进行修改,最好使用$set方法进行修改,使用方法如下:

this.$set(this.form,'key','value')

这样就不会使得Vue无法监听对象属性值的变化。但是在Vue中,还是应该尽量避免超多层结构对象的使用,因为层数一旦过多,及时使用$set也有可能使得Vue无法监听该对象的属性变化

补充(源于Vue官网):

Vue 无法检测 property 的添加或移除。由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的。

对于已经创建的实例,Vue 不允许动态添加根级别的响应式 property。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式 property。

5、参考文章:

  1. element ui表单验证原理_akatukijohi的博客-CSDN博客_element表单验证原理
  2. 深入响应式原理 — Vue.js (vuejs.org)
Logo

前往低代码交流专区

更多推荐