记录下vue中有关DOM的两个方法$nextTick()与$set(),因为vue是数据驱动视图(MVVM)模式,不需要手动操作DOM,所以有关DOM的方法不常用,下面记录一下这两种方法的使用场景
1.this.$nextTick()
this.$nextTick()是在下次 DOM 更新循环结束之后执行延迟回调
场景一:假设我们改变了某个DOM内部的文本,此时用this.$refs打印DOM并不能看到文本变化,此时需要在this.$nextTick(()=>{})的回调函数中调用,在DOM更新后打印
场景二:DOM根据data中的数组循环渲染,在往该数组中push新成员后,取新的DOM盒子渲染echants,此时调用document.getElementById()会报错‘Cannot read property 'getAttribute' of null’,因为此时虽然数组改变了,但是DOM还没有渲染,应把document.getElementById()方法写在this.$nextTick()的回调中
2·this.$set()
语法:this.$set(target,index,value),对应参数分别为:目标数组,索引,值
场景:当你发现修改了数组对象中的一个属性,控制台能打印出来,但是视图并没有更新时,首先考虑下使用this.$set()方法
例子:在组件中写下如下代码
<div v-for="item in list" :key="item.id"> <div>{{item.name}}div> <div>{{item.phone}}div>div>
data中定义list
data() { return { list: [ { id: 1, name: '小刘', phone: '华为' }, { id: 2, name: '小王', phone: '苹果' } ] } },
mounted钩子中修改数组对象的属性值并打印,可以看出打印结果与视图不一致:
mounted() { this.list[0] = { id: 1, name: '小刘', phone: '苹果' } console.log(this.list) },
数据更新了而视图并没有更新
修改语法,使用$set(),再次查看输出,可以看到问题已经解决
mounted() { this.$set(this.list, 0, { id: 1, name: '小刘', phone: '苹果' }) console.log(this.list) },
以前觉得$set()方法的使用场景自己遇不到,直到接手一个大坑项目,data中定义的一些复杂数据结构vue无法监听,虽然暂时没去了解$set()的原理,但是它可以解决问题