Vue.$nextTick结合Echarts详解面试考点

3,496 阅读3分钟

这是我参与新手入门的第1篇文章

前言

不知道有没有同学和我一样,没有经历过项目的问题很难印象深刻地记住并在遇到问题时适时运用。所以今天就以一个demo举例说明nextTick在echarts图表场景下的使用,并简单描述不使用nextTick出现的问题,这样大家就能印象深刻地了解其应用场景啦。

需求:对在职人员的年龄和性别进行分析,切换年龄、性别tab展示切换相对应的图表

功能页面如下:

微信图片_20210705203159.png

遇到的问题

  • 现象一:当我在data里写死数据时可以展示图表,调用接口就无法展示
  • 现象二:用上nextTick就可以展示了
  • 现象三:切换年龄、性别tab时,我使用v-show咋害能不展示呢

知识点

  • Vue 的生命周期 ?页面渲染发生在哪一步?
  • v-show v-if 获取dom元素的宽高 ?
  • nextTick 的原理 ?
  • echarts 的渲染机制 ?

代码解析

关键代码如下:

  mounted(){
      // 获取接口数据
      this.data = await apiData.getPersonManagerData()
      const { personAnalyse } = this.data
      //const { personAnalyse1 } = this.data
      await nextTick()
      console.log('Now DOM is updated')
      this.drawPersonAnalyse(personAnalyse)
      //this.drawPersonAnalyse(personAnalyse1)
  },
  methods:{
      changeType(index) {
          this.currentIndex = index
          if (this.currentIndex === '2') {
            this.$nextTick(() => {
              this.chart = echarts.init(this.$refs.personAnalyse)
            })
          } else {
            this.$nextTick(() => {
              this.chart = echarts.init(this.$refs.personAnalyse1)
            })
          }
      },
  }
}

知识点详解

1、 vue是如何更新dom的?

首先,我们来看下vue的生命周期,相信有参加过面试的同学那几个步骤都会背了,但是有一个关键的点,mounted是平常写代码的时候最常用的,mounted是完成页面渲染之后触发的。

微信图片_20210707103936.png

Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。 (来源:官网)

原因分析:首次进入页面,在mounted之前已经完成了页面渲染,所以使用默认数据data一直没有改变,因此图表的dom是可以获取到的。

所以这个很好的解析了现象一:

当我在data中写假数据时,图表是能够出来的,但是从接口获取数据更改了data又没有使用nextTick图表就消失了。

2、nextTick用法?

用法:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。(来源:官网)

这解析了现象二:

接上现象一:当我从接口获取数据时,监听到数据变化dom开始更新了,所以要等dom更新完毕用上nextTick然后去获取dom对象添加图表数据,此时图表就出来啦。

贴上官网的用法

await nextTick()
console.log('Now DOM is updated')
createApp({
  // ...
  methods: {
    // ...
    example() {
      // modify data
      this.message = 'changed'
      // DOM is not updated yet
      this.$nextTick(function() {
        // DOM is now updated
        // `this` is bound to the current instance
        this.doSomethingElse()
      })
    }
  }
})

3、v-show v-if 获取dom元素的宽高 ?

v-show 相当于display:none

display:none 当元素的高度为百分比时就获取不到

这解释了现象三:当我使用v-show时,nextTick也用了,图表咋还不出来呢?因为没有dom元素没有宽高呀。图表就出不来也不报错

4、echarts渲染机制

先要有dom元素再setOption(大概是一句废话,但是为了完整性还是说一说)

接上现象三,现象四:修改为v-if的方式并且使用nextTick终于完整了,道理同现象二。

总结

以上就是关于一个echarts图表引发的全部问题和思考,解决办法有很多种,我只是说明了其中一种。只要知道具体原因问题就能迎刃而解啦