必看!vue之nextTick原理

138 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

引言

vue框架已经陆续出了2和3的版本,由于vue框架的异步批量更新机制的设计,导致我们无法直接从dom上获取到最新修改的数据。基于此vue提供了数据更新后获取最新dom更新的数据api,这就是今天的主角-nextTick!

nextTick使用

如下是一段简单的测试,当我们修改数据name后,试图获取修改数据后的dom内容,通过例子发现直接获取dom的内容是无法获取的。由于数据修改是同步的,而dom更新是异步的,所以我们获取的总是上一次未更新的dom。通过vue的nextTick提供的api可以方便的获取最新的dom节点。

使用方式

this.$nextTick(()=>{
    console.log(xxx)//获取当前更新后的dom节点信息
 })

测试例子

<template>
  <div id="app">
    <p ref="divEle">{{name}}</p>
    <div  @click="changeName()">修改name </div>
  </div>
</template>

<script>

export default {
  name: 'App',
  data() {
    return {
      name:"xiao ming"
    }
  },

  methods:{
    changeName(){
      this.name = "big ming"
      //直接获取
      console.log(this.$refs.divEle.innerHTML)//输出xiao ming

      //通过nextTick获取
      this.$nextTick(()=>{
        console.log(this.$refs.divEle.innerHTML)//输出da ming
      })
    },
  }
}
</script>

nextTick原理介绍

为什么修改数据后,无法第一时间获取到最新的dom相关信息?这个和js的异步事件是紧密联系的。我们知道js的设计是单线程的,js的事件整体划分为三类,一类是同步代码,一类是宏任务事件,一类是微任务事件。而宏任务和微任务都是异步的事件。js在执行三类事件的时候,先从上到下扫码js代码,如果是同步代码直接执行,如果遇到了宏任务和微任务则将两类任务放到各自的队列中稍后执行。当所有的同步代码执行完成,再扫描各自的队列等待各自的异步任务触发。回到vue上,nextTick的设计就是由于vue数据更改是同步的,但是dom是批量的异步更新,所以我们修改数据后,直接获取dom只能拿到上一次的dom。而nextTick就是基于dom更新异步的回调触发的事件,至于其底层设计是宏任务还是微任务?vue采用的是优雅降级的操作,判断如果浏览器环境支持微任务就让其进入微任务队列,如果不支持则降级为宏任务执行。

总结

以上是对nextTick的简单理解,谢谢支持。