背景:
vue数据变化就会导致视图的更新,这个过程是异步的—异步更新,但是有的时候我们又需要立刻拿到这个结果 (这个时候就要用到$nextTick())
我们修改一个属性的时候 通过$refs获取dom或组件的时候,拿到的值是没有更新过的 因为
在vue中 dom渲染是异步执行的 也就是我们拿值的时候dom还没有更新!
所以官方为我们提供了 $nextTick方法 原理就是 在DOM更新完成后执行回调函数
代码演示1: 老师举的例子
data() {
return {a:1}
}
this.a = 2
console.log('视图') // 这个时候拿不到更改后的2这个值的,因为还没等把变成2,这里就已经输出了, 而且vue数据变化会导致视图更新,是异步的
那怎么才能拿到呢?
this.$nextTick( () => {
console.log('视图) // 现在就可以拿到更改后的值了,放在回调里面,现在是异步的
} )
setTimeOut(()=> {
console.log('视图) // 延迟
})
代码演示2:
<template>
<div>
<span ref="number">{{ number }}</span>
<button @click="add">加1</button>
</div>
</template>
<script>
export default {
data () {
return {
number: 0
}
},
methods: {
add () {
this.number++
console.log(this.$refs.number.innerHTML) // 0
this.$nextTick(() => {
console.log("DOM更新后触发$nextTick函数")
console.log(this.$refs.number.innerHTML) // 1
})
}
},
}
</script>
图示说明:
$nextTick使用场景:
点击搜索按钮通过dom添加focus()方法
代码演示3:
<template>
<div>
<button v-if="isSearch" @click="search">搜索</button>
<input v-if="isShow" id="" ref="input" type="text" name="">
</div>
</template>
<script>
export default {
data() {
return {
isShow: false,
isSearch: true
}
},
methods: {
search() {
this.isShow = true
this.isSearch = false
// dom渲染是异步的: dom发生变化
// 下面这个方法 快 dom更新 慢
// dom慢 我比他还慢
this.$nextTick(() => {
this.$refs.input.focus() // 希望在随后的代码中使用更新后的视图,那就要把操作写在nextTick的回调函数中
})
}
}
}
</script>
<style lang="less" scoped>
</style>
大白话: 这个代码就是这样的: 我点击搜索按钮,搜索按钮隐藏,input框显示并且自动获取焦点 . 好,接着说下面的, 老是说dom渲染是异步的异步的,dom还没有更新,到底是个什么意思呢? 是这样的啊, 直接写 this.$refs.input.focus() ,会出现什么效果呢? 自动获取焦点失败,为什么会失败呢? 这就是我们的dom渲染是异步的意思,就是慢的意思(渲染: 就是说把搜索框变成input框获取焦点这个过程 是慢的),,所以我在this.$refs.input.focus() 已经拿到值的时候(这个动作是快的,,虽然说是调用focus方法,但是也相当于是说去拿值)在获取焦点之前就去做了 ,但是dom渲染是异步的嘛,所以它不会出来自动获取焦点的效果,,然后把这句话写在$nextTick() 里面就能出来,就是说,可以在dom渲染更新完了以后再去调用focus方法,就可以了,就是说,dom更新异步,慢, 我夹在$nextTick里面,我就dom渲染还慢,就可以实现这个效果了,,
还记得小智聊天吗? 我的滚动条总是不能滚动到最底部,是什么原因呢? 也就是说啊: dom更新是异步的,但是我滚动条不是啊,所以我在小智最后一条回复我以前我就把滚动条执行了,哎,慢一点嘛,等小智回复我我再滚动嘛,所以我就把滚动事件放在$nextTick()里面,比小智回复我还慢
图示说明: