Bootstrap

关于VUE中v-for循环的dom使用ref获取不到问题

背景:

初学vue做练习项目的时候,基于vue2.0版本使用refs属性获取v-for循环的dom时出现获取不到dom的情况,尝试采用原生的方法出现同样的情况。查了很多资料没有找到对应的详细说明,现将我发现的一些问题分享给大家。

html部分

<div class="food-group" v-for="(item,index) in goods" :key="index" ref="group">
    ....
</div>
复制代码

定义的方法methods

  methods: {
    getHeightList() {
      let height = 0;
      this.heightList.push(height);
      // let list = this.$refs.goods.getElementsByClassName("food-group");
      console.log(this.$refs);      
      console.log(this.$refs.group);
    }
  },
复制代码

尝试在mounted生命周期里面执行方法获取refs的DOM

  mounted() {
    this.$nextTick(() => {
      this.menuScroll = new BScroll(this.$refs.menu);
      this.goodsScroll = new BScroll(this.$refs.goods);
      this.getHeightList();
    });
  }
复制代码

出现的结果

可以发现这里打印this.refs里面是有group对应的Dom的,但是在下面答应对应的Dom的时候出现undefined的情况,下面是尝试把ref获取改成d原生获取的方法。

  methods: {
    getHeightList() {
      let height = 0;
      this.heightList.push(height);
      let list = this.$refs.goods.getElementsByClassName("food-group");
      //this.$refs.goods是刚才要获取的Dom的父元素,food-group是要获取的Dom的类名
      console.log(list);      
      console.log(list.length);
    }
  },
复制代码

出现的结果

可以看到这里出现的情况和上面ref获取出现的情况是一样的,打印出来是有的,但是一旦输出结果却发现length是0,也就是没有获取到。

使用debugger调试的发现:

在操作dom的自定义函数执行前后加入debugger调试,发现在该函数执行的时候,数据并没有绑定,dom也还是没有渲染的状态,这和网上一些帖子讲的是一样的,但是问题来了,该函数执行也是在this.$nextTick里面执行的,应该是Dom渲染完成菜执行的。这里就引出了这里的关键性的问题:

  • vue组件初始化到第一次渲染完成,也就是mounted周期里面,只是把组件模板的静态数据渲染了,动态绑定的Dom,并没有初始化,所以我们在mounted周期里面操作获取dom是获取不到的。
解决方案:
  1. 把this.$nextTick放在你获取到v-for绑定的数据并赋值之后,也就是触发响应式更新之后在操作。
  2. 把操作dom的操作放到updated生命周期里面执行,但是这样会出现,每次跟新视图,都会触发该操作。
;