以下内容若有问题烦请即时告知我予以修改,以免误导更多人。
- nextTick
- es5源码
- 关于setTimeout(fn,0)
- 讨论点
- 常用示例
- 1.mounted时更新
- console
- 2.更改子组件更新时间
- console
- 3.同时更改父组件更新时间
- console
- 4.nextTick顺序问题
- console
- 1.mounted时更新
- 总结
nextTick
在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
vue这么做是因为频繁的更新dom是特别耗费性能的,所以搞了一个批处理更新,把所有的update操作放到任务队列中,等主线程中执行栈的所有同步任务执行完毕,系统就会读取任务队列。
es5源码
1 | /** |
关于setTimeout(fn,0)
理解 JavaScript 中的 macrotask 和 microtask
JavaScript 主线程拥有一个
执行栈
以及一个任务队列
,主线程会依次执行代码,当遇到函数时,会先将函数 入栈
,函数运行完毕后再将该函数 出栈
,直到所有代码执行完毕。
- macrotasks: setTimeout, setInterval, setImmediate, I/O, UI rendering
- microtasks: process.nextTick, Promises, Object.observe(废弃), MutationObserver
在每一次事件循环中,macrotask 只会提取一个执行,而 microtask 会一直提取,直到 microtasks 队列清空。
讨论点
- 父组件nextTick的触发在子组件DOM完成前还是完成后?
常用示例
- DOM
1 | <div id="J_app"> |
1.mounted时更新
- 父组件
1 | (function() { |
- 子组件
1 | (function() { |
console
1 | 父组件beforeCreate |
nextTick写在数据更改前不能拿到更新后的数据。
2.更改子组件更新时间
1 | (function() { |
console
1 | 父组件beforeCreate |
若子组件在mounted即更新,子组件的update动作会在父组件的beforeUpdate之后updated之前执行。
反之则更新后子组件自己执行update,并且由于父组件nextTick写在数据更改之前,导致先执行父组件nextTick再执行父组件的update动作。
3.同时更改父组件更新时间
1 | (function() { |
console
1 | 父组件beforeCreate |
若父、子组件的更新延时相同,则会各自执行各自的update动作,子组件优先。
4.nextTick顺序问题
nextTick应写在数据更改后
- 父组件
1 | (function() { |
- 子组件
1 | (function() { |
console
1 | 父组件beforeCreate |
如果子组件nextTick写在数据更改前,则会在父组件mouted之后beforeUpdate之前执行nextTick。实际应在updated之后执行nextTick,这样nextTick才能拿到最新的数据。
- 推荐在updated中执行$nextTick
1 | updated: function() { // 数据更新之后调用 |
总结
父组件nextTick的触发在子组件updated后。
若子组件在mounted即更新,子组件的update动作会在父组件的beforeUpdate之后updated之前执行。反之则更新后子组件自己执行update,不会影响父组件的nextTick。
若父、子组件的更新延时相同,则会各自执行各自的update动作,子组件优先。
nextTick都需写在各自组件的updated之后。
更多内容可以订阅本人微信公众号,一起开启前端小白进阶的世界!
公众号不发文的时候推送一些我觉得好用的前端网站或者看到的一些问题的解决方案,也更便于大家交流,就酱。