开发时遇到一个bug:通过v-for渲染出几个搜索条件组件(对应的数组数据记为selectList),通过其他方式修改了这些筛选条件对应的数据selectList,之后通过$refs得到的实例去触发对应子组件的方法(类似:this.$refs.test[index].changeValue(itemValue)),发现子组件的方法中的数据对应不上,会与其他筛选组件的数据错位。

        发现:

  1. 组件通过v-for渲染出来,使用了selectList中的其中的属性id作为key值,改变后的selectList中每组数据都有变化,但其中只有一组数据id与之前不同。
  2. 故id未变化的组件对应key不变,则这些组件并未完全重新渲染
  3. id变化的组件以及其后的组件changeValue方法中拿到的值是其他组数据的值,index是对应selectList的索引,故设想是否是$refs得到的index对应的组件实例并非是selectList的索引对应的值?打印一下,发现果然key值改变的组件对应$refs得到的实例数据中的最后一个,看来key值更新的实例会以push的方式加入$refs实例数组中。

 用简单数据测试下:

<template>
  <div class="box">
    <div @click="change">click</div>
    <div
      ref="testFor"
      v-for="(item, index) in dataArr"
      :key="'test' + item.key + '-' + index"
    >
      {{ item.name }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dataArr: [
        { name: "A", key: "1" },
        { name: "B", key: "2" },
        { name: "C", key: "3" },
        { name: "D", key: "4" },
      ],
    };
  },
  mounted() {
  },
  methods: {
    change() {
      this.dataArr = [
        { name: "A", key: "1" },
        { name: "BB", key: "22" },
        { name: "C", key: "3" },
        { name: "DD", key: "4" },
      ];
      console.log(this.$refs.testFor);
    },
  },
};
</script>

click后,查看页面打印,果然更新key值的vue实例在最后:

页面:

展开最后一个div:

             

查找资料,发现$refs中的实例确实是以push方式添加。

 总结:所以简单来说,就是vue通过v-for渲染的组件/元素,更新key值的组件/元素会push进当前的ref,所以会存在通过$refs[index]拿到的组件不对应原数组对应的index数据。

资料参考:[vue 源码系列] ref 与 $refs 如何关联_weixin_34289454的博客-CSDN博客

Logo

前往低代码交流专区

更多推荐