背景:
初学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是获取不到的。
解决方案:
- 把this.$nextTick放在你获取到v-for绑定的数据并赋值之后,也就是触发响应式更新之后在操作。
- 把操作dom的操作放到updated生命周期里面执行,但是这样会出现,每次跟新视图,都会触发该操作。