背景:

vue数据变化就会导致视图的更新,这个过程是异步的—异步更新,但是有的时候我们又需要立刻拿到这个结果 (这个时候就要用到$nextTick())

我们修改一个属性的时候 通过$refs获取dom或组件的时候,拿到的值是没有更新过的 因为

在vue中 dom渲染是异步执行的 也就是我们拿值的时候dom还没有更新!

所以官方为我们提供了 $nextTick方法 原理就是 在DOM更新完成后执行回调函数


举了三个例子,还不懂我就是猪

代码演示1: 老师举的例子

  1. data() {
  2. return {a:1}
  3. }
  4. this.a = 2
  5. console.log('视图') // 这个时候拿不到更改后的2这个值的,因为还没等把变成2,这里就已经输出了, 而且vue数据变化会导致视图更新,是异步的
  6. 那怎么才能拿到呢?
  7. this.$nextTick( () => {
  8. console.log('视图) // 现在就可以拿到更改后的值了,放在回调里面,现在是异步的
  9. } )
  10. setTimeOut(()=> {
  11. console.log('视图) // 延迟
  12. })

代码演示2:

  1. <template>
  2. <div>
  3. <span ref="number">{{ number }}</span>
  4. <button @click="add">加1</button>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. data () {
  10. return {
  11. number: 0
  12. }
  13. },
  14. methods: {
  15. add () {
  16. this.number++
  17. console.log(this.$refs.number.innerHTML) // 0
  18. this.$nextTick(() => {
  19. console.log("DOM更新后触发$nextTick函数")
  20. console.log(this.$refs.number.innerHTML) // 1
  21. })
  22. }
  23. },
  24. }
  25. </script>

图示说明:

image.png


$nextTick使用场景:

点击搜索按钮通过dom添加focus()方法

代码演示3:

  1. <template>
  2. <div>
  3. <button v-if="isSearch" @click="search">搜索</button>
  4. <input v-if="isShow" id="" ref="input" type="text" name="">
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. data() {
  10. return {
  11. isShow: false,
  12. isSearch: true
  13. }
  14. },
  15. methods: {
  16. search() {
  17. this.isShow = true
  18. this.isSearch = false
  19. // dom渲染是异步的: dom发生变化
  20. // 下面这个方法 快 dom更新 慢
  21. // dom慢 我比他还慢
  22. this.$nextTick(() => {
  23. this.$refs.input.focus() // 希望在随后的代码中使用更新后的视图,那就要把操作写在nextTick的回调函数中
  24. })
  25. }
  26. }
  27. }
  28. </script>
  29. <style lang="less" scoped>
  30. </style>

大白话: 这个代码就是这样的: 我点击搜索按钮,搜索按钮隐藏,input框显示并且自动获取焦点 . 好,接着说下面的, 老是说dom渲染是异步的异步的,dom还没有更新,到底是个什么意思呢? 是这样的啊, 直接写 this.$refs.input.focus() ,会出现什么效果呢? 自动获取焦点失败,为什么会失败呢? 这就是我们的dom渲染是异步的意思,就是慢的意思(渲染: 就是说把搜索框变成input框获取焦点这个过程 是慢的),,所以我在this.$refs.input.focus() 已经拿到值的时候(这个动作是快的,,虽然说是调用focus方法,但是也相当于是说去拿值)在获取焦点之前就去做了 ,但是dom渲染是异步的嘛,所以它不会出来自动获取焦点的效果,,然后把这句话写在$nextTick() 里面就能出来,就是说,可以在dom渲染更新完了以后再去调用focus方法,就可以了,就是说,dom更新异步,慢, 我夹在$nextTick里面,我就dom渲染还慢,就可以实现这个效果了,,
还记得小智聊天吗? 我的滚动条总是不能滚动到最底部,是什么原因呢? 也就是说啊: dom更新是异步的,但是我滚动条不是啊,所以我在小智最后一条回复我以前我就把滚动条执行了,哎,慢一点嘛,等小智回复我我再滚动嘛,所以我就把滚动事件放在$nextTick()里面,比小智回复我还慢

图示说明:
image.png


$nextTick返回promise对象