ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Vue.nextTick 的原理和用途

2021-03-16 23:04:48  阅读:133  来源: 互联网

标签:nextTick 异步 Vue 队列 sopPopups 用途 执行


一、问题及原因
在这里插入图片描述
在项目中,我们会发现sopPopups的值在被修改为true后,结果打印出来的sopPopups值还是之前的false,但是在this.$nextTick中打印sopPopups的值为true。这是为什么呢??
原因:
Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新,dom更新是一个异步过程。
具体来说,异步执行的运行机制如下
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
所以,Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。
二、nextTick的原理
结合源码
在这里插入图片描述
nextTick把任务推到一个数组里,在下一个tick去执行这个任务。

1、首先修改数据,this.sopPopups=true和console.log()这是同步任务。同一事件循环的所有的同步任务都在主线程上执行,形成一个执行栈,此时还未涉及 DOM 。
Vue 开启一个异步队列,并缓冲在此事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。
2、同步任务执行完毕,开始执行异步 watcher 队列的任务,更新 DOM 。Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MessageChannel 方法,如果执行环境不支持,会采用 setTimeout(fn, 0) 代替。
3、DOM 更新循环结束之后,系统就会读取"任务队列",看看里面有哪些事件,此时通过 Vue.nextTick 获取到改变后的 DOM 。通过 setTimeout(fn, 0) 也可以同样获取到。

简单总结事件循环:
同步代码执行 -> 查找异步队列,推入执行栈,执行dom更新,执行Vue.nextTick[事件循环1] ->查找异步队列,推入执行栈,执行dom更新,执行Vue.nextTick[事件循环2]…

二、nextTick的用法
需要在视图更新之后,基于新的视图进行操作。
1、写法,由源码可看出,nextTick有2种写法
(1)
this.sopPopups = true
this. n e x t T i c k ( ( ) = > c o n s o l e . l o g ( t h i s . s o p P o p u p s ) ) ( 2 ) p r o m s i e 写 法 t h i s . s o p P o p u p s = t r u e t h i s . nextTick(() => { console.log(this.sopPopups) }) (2) promsie写法 this.sopPopups = true this. nextTick(()=>console.log(this.sopPopups))(2)promsie写法this.sopPopups=truethis.nextTick().then(() =>{console.log(this.sopPopups)})
2、需要注意的是,在 created 和 mounted 阶段,如果需要操作渲染后的试图,也要使用 nextTick 方法。
****注意 mounted 不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用 vm.KaTeX parse error: Expected '}', got 'EOF' at end of input: …on () { this.nextTick(function () {

})
}

标签:nextTick,异步,Vue,队列,sopPopups,用途,执行
来源: https://blog.csdn.net/zaoqinghuan/article/details/114904399

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有