Vue2面试考点之$nextTick原理解析

 更新时间:2023年05月30日 08:14:58   作者:前端技术栈  
平时在获取真实DOM的时候获取不到最新的DOM元素,使用$nextTick就可以,那为什么$nextTick就可以获取到最新的DOM元素呢,本文就来带着这两个问题来解析一下nextTick的原理

nextTick原理

平时在获取真实DOM的时候获取不到最新的DOM元素,使用$nextTick就可以

为什么$nextTick就可以获取到最新的DOM元素?

带着以上问题,来解析nextTick的原理

为什么获取不到最新的DOM元素

因为Vue修改视图是异步执行的,这也是为了优化性能,在我们修改data中的数据时,Vue内部监听到依赖数据发生了改变,通过dep通知组件的watcher执行视图更新,每一次视图更新都需要重新生成vnode再进行新旧vnode比对,生成DOM元素挂载到页面上,这一轮操作是非常消耗性能的,所以Vue内部会把页面更新watcher推入到一个队列中,并加入了节流方法,当同步代码执行完了之后才会把队列中的watcher拿出来遍历更新视图,我们在使用this.$refs获取DOM的时候是同步代码,其实DOM还没有更新,所以是获取不到的

为什么使用$nextTick就可以获取到最新DOM

Vue的视图更新是异步执行的,使用的就是nextTick,这也是能获取到最新DOM的原因,在Vue内部有一个nextTick函数,他也是使用队列去处理回调函数,并不是调用后就马上执行,首先是推入到一个队列中,当所有的同步代码执行完的时候再通过循环取出调用,接下来可以通过代码了解

let callback = []
let pending = false
let timerFunc
function flush() {
  callback.forEach((cb) => cb())
  pending = false
  callback = []
}
// 处理兼容问题
if (Promise) {
  timerFunc = () => {
    Promise.resolve().then(flush)
  }
} else if (MutationObserver) {
  let observe = new MutationObserver(flush)
  let textNode = document.createTextNode(1)
  observe.observe(textNode, {
    characterData: true,
  })
  timerFunc = () => {
    textNode.textContent = 2
  }
} else if (setImmediate) {
  // ie浏览器支持得定时器
  timerFunc = () => {
    setImmediate(flush)
  }
}
export function nextTick(cb) {
  callback.push(cb)
  // Promise.then
  if (!pending) {
    console.log('执行了')
    timerFunc() // 这个方法就是异步方法
    pending = true
  }
}
 

1.定义一个callback数组,每次调用nextTick就会把回调函数push到callback数组中,因为callback.push是同步代码,timerFunc是异步代码,所以执行完所有push后才会调用timerFunc

2.那么视图更新和获取DOM的流程是怎么样的呢

通过伪代码来解释

data(){
    return {
        name: 'zs',
        list: [1,2,3]
    }
}
this.name = 'ls'
this.list.push(4)
const fn = () => {
  this.$el.innerHTML // 获取最新DOM
}
this.$nextTick(fn)

this.name和this.list修改了2个数据,会触发两次视图更新,这个时候就会把watcher推入到队列中,下面调用了$nextTick获取DOM,nextTick中的fn函数也会推入到队列中,这个时候的数组是这样的[watcher,fn]通过循环调用,先执行视图更新,后获取DOM就可以获取到最新DOM了

到此这篇关于Vue2面试考点之$nextTick原理解析的文章就介绍到这了,更多相关Vue2 $nextTick内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于Vue实例生命周期(全面解析)

    基于Vue实例生命周期(全面解析)

    下面小编就为大家带来一篇基于Vue实例生命周期(全面解析)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • 详解vue route介绍、基本使用、嵌套路由

    详解vue route介绍、基本使用、嵌套路由

    vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用,这篇文章主要介绍了vue route介绍、基本使用、嵌套路由,需要的朋友可以参考下
    2022-08-08
  • Vue中nprogress页面加载进度条的方法实现

    Vue中nprogress页面加载进度条的方法实现

    这篇文章主要介绍了Vue中nprogress页面加载进度条的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • vue-dplayer视频播放器组件的使用详解

    vue-dplayer视频播放器组件的使用详解

    Vue-DPlayer是一个易于使用、高性能的基于Vue.js的视频播放器组件,这篇文章将为大家详细介绍一下vue-dplayer视频播放器组件的安装与使用,需要的小伙伴可以参考下
    2023-09-09
  • vue刷新子组件、重置组件以及重新加载子组件项目实战记录

    vue刷新子组件、重置组件以及重新加载子组件项目实战记录

    在vue开发中出于各种目的,我们常常需要让组件重新加载渲染,这篇文章主要给大家介绍了关于vue刷新子组件、重置组件以及重新加载子组件的相关资料,需要的朋友可以参考下
    2023-12-12
  • 在vue中使用回调函数,this调用无效的解决

    在vue中使用回调函数,this调用无效的解决

    这篇文章主要介绍了在vue中使用回调函数,this调用无效的解决,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • vuex页面刷新数据丢失问题的四种解决方式

    vuex页面刷新数据丢失问题的四种解决方式

    vuex是大家使用vue时大多数都会选择的,但是当页面刷新之后vuex数据会丢失,下面这篇文章主要给大家介绍了关于vuex页面刷新数据丢失问题的四种解决方式,需要的朋友可以参考下
    2022-02-02
  • elementUI table表格动态合并的示例代码

    elementUI table表格动态合并的示例代码

    这篇文章主要介绍了elementUI table表格动态合并的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • vue3数组或对象赋值不更新解决方法示例

    vue3数组或对象赋值不更新解决方法示例

    这篇文章主要为大家介绍了vue3数组或对象赋值不更新解决方法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • 解决Vue3 echarts v-show无法重新渲染的问题

    解决Vue3 echarts v-show无法重新渲染的问题

    这篇文章主要介绍了Vue3 echarts v-show无法重新渲染的问题,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09

最新评论