ref就是用来获取dom的
用法:给dom元素设置一个ref值,通过this.$refs.设定的值来获取到被绑定的dom元素
<div id="test" ref="aaa">123123</div>
mounted() {
const a = document.getElementById('test')
console.log(a);
console.log(this.$refs.aaa);
}
两个打印都会出现这个 id 为 test 的 div 元素。
注意:设置的时候用ref,但是在获取值的时候是 $refs
$nextTick()
vue在数据发生改变的时候,并不会实时更新DOM,更新DOM的操作是异步的,所以一旦出现在数据改变后就马上需要获取DOM值来进行后续操作时,此时是拿不到数据更新后的DOM值的,而$nextTick()就解决了这个问题,$nextTick()接收一个函数,它会在DOM更新后被调用,可以帮助我们拿到DOM更新后的数据。
<div id="test" ref='num' @click='changeNum'>{{ num }}</div>
<script>
export default {
data() {
return {
num: '111111',
}
},
methods: {
changeNum() {
this.num = '2222222'
console.log(this.$refs.num.innerHTML)//111111
this.$nextTick(() => {
console.log('nextTick', this.$refs.num.innerHTML)//2222222
alert('nextTick')
})
}
}
}
</script>
$nextTick() 是一个微任务,涉及到事件循环可能会存在一些疑惑(其实就是我自己),在事件循环机制中任务的执行顺序是先执行同步任务,再执行异步任务,而异步任务中也是分为微任务和宏任务的,它们和 DOM 之间的关系是,先同步任务全部执行完,去执行微任务,再进行 DOM 渲染,最后执行宏任务,那么 $nextTick() 一个微任务应该是在 DOM 更新前就已经完成了呀,为什么是异步拿到DOM更新后的数据 ?其实是没问题的,$nextTick()只是先拿到了数据更新后的结果,但是在执行$nextTick()时DOM还没有进行渲染。
上图代码中,是点击这个 id 为 test 的 div,就会把 1111 变成 22222 同时在控制台打印结果,但是加上 alert 后,alert 会阻塞代码,所以当控制台中 $nextTick() 已经拿到数据更新结果(即222222)时,DOM渲染被 alert 阻塞,还是11111,也验证了事件执行顺序是没错的,只是 $nextTick() 先拿到了更新后的数据而已。
而且写在 Vue 的 created 生命周期内的代码也是需要套在 $nextTick() 中的,因为在 created 时都还没进行DOM渲染。