Vue实战时用到的API(二):$nextTick

1,406 阅读1分钟

什么是$nextTick


老规矩先来看下官方文档对它的介绍:

  • 参数
    • {Function} [callback]
    • {Object} [context]
  • 用法: 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

用途


首先我们来讲解一些常见的场景:

  1. 假设我们修改了一个Dom里的数据,又要马上去获取这个数据,应该怎么做呢。代码如下
<div id="demo" @click="getText($event)">{{text}}</div>
<script>
 new Vue({
  el:'#demo',
  data:{
    text:'修改前的数据'
  },
  methods:{
    getText(event){
      this.text='修改后的数据'
      console.log(event.target.innerText)
    }
  }
})
</script>

在上面提供的代码里,当我们点击 div 时,会调用方法去改变 div 内部的值,此时我们想输出这个 div 内部的值会是什么呢? 42X(M%DSN)71PHC(IEI74.png

结果依然是修改前的值,这跟我们想要的需求不大一样,加上$nextTick试试:

<div id="demo" @click="getText($event)">{{text}}</div>
<script>
  new Vue({
    el:'#demo',
    data:{
      text:'修改前的数据'
    },
    methods:{
      getText(event){
        this.text='修改后的数据'
        this.$nextTick(function(){
          console.log(event.target.innerText)
        })

      }
    }
  })
 </script>

在这里我们将输出放在了 $nextTick 的回调函数里,这保证了里面的输出会在DOM更新之后再调用,此时的输出应该是什么呢? $T(0[7QO5(]HVQU)P2ZSK.png

这个时候我们的需求才算达成。

  1. 当我们想要在Vue生命周期的 created() 钩子函数进行的DOM操作一定要放在 $nextTick() 的回调函数中,因为在 created() 时DOM还没开始渲染,此时对它的操作自然都是徒劳的,当我们将操作放在 $nextTick() 的回调函数后,就能保证当操作执行时已经存在DOM结构

实战遇到的一个问题


我想实现的需求类似是:在父组件的下拉框选择一个值,通过props传递给子组件。同时触发子组件的函数去获取这个值作为一些接口的参数,代码如下:

<div id="blog-post-demo" class="demo">
  <select  v-model="fatherTitle" @change="change">
    <option :value="post" v-for="post in posts" :key="post">{{post}}</option>
  </select>
  <blog-post :title="fatherTitle" ref="child"></blog-post>
</div>
<script>
  Vue.component("blog-post", {
    props: ["title"],
    template: "<h3>{{ title }}</h3>",
    methods:{
      getResult(){
        console.log(this.title)
      }
    }
  });
  new Vue({
    el: "#blog-post-demo",
    data: {
      posts: [1,2,3],
      fatherTitle:''
    },
    methods:{
      change(){
        this.$refs.child.getResult()
      }
    }
  });
</script>

如上我先打印出这个值,但出现了很奇怪的情况,每次获取到的值都是上一次选中的选项,如第一次是 undefined ,第二次是第一次选中的值。改了很久,最终还是用了上文提到的 $nextTick 去解决,在 change 方法中修改了点,如下:

change(){
  this.$nextTick(function(){
    this.$refs.child.getResult()
  })   
}

这样我们就能准确的获取每次选中的结果了,但是我还是觉得没解决到点上,如果有大佬看出的话,可以帮我解惑下谢谢!