经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Vue.js » 查看文章
Vue源码学习(十三):nextTick()方法
来源:cnblogs  作者:养肥胖虎  时间:2023/10/23 8:53:39  对本文有异议

好家伙,nextTick,

(...这玩意,不太常用)

 

1.什么是nextTick

在Vue中,nextTick是一个用于异步执行回调函数的方法。

它在Vue更新DOM后被调用,以确保在下一次DOM更新渲染完成后执行回调函数。

而事实上,我们把队列处理的操作封装到了nexrTick方法中.

 

实际上,Vue在更新DOM时是异步执行的。

当你修改Vue实例的数据时,Vue会对依赖这些数据的虚拟DOM进行重新渲染,然后更新到真实的DOM上。

但是,DOM更新是在下一个事件循环中执行的,而不是立即执行。

所以,如果你想在DOM更新后执行一些操作,你就可以使用nextTick方法。

这个方法会将回调函数推入到微任务队列中,并在DOM更新后执行

这样可以确保你在操作更新后的DOM,比如获取元素的宽高等,而不是得到修改前的值。

 

举一个非常简单的例子

  1. Vue.Mixin({ //全局
  2. created: function b() {
  3. // console.log('b----2')
  4. }
  5. })
  6. let vm = new Vue({
  7. el: '#app', //编译模板
  8. // data: {
  9. // },
  10. data() {
  11. // console.log(this)
  12. return {
  13. msg:'牛肉',
  14. arr: [1, 2, 3],
  15. }
  16. },
  17. created() {
  18. // console.log(555)
  19. }
  20. })
  21. console.log(vm.msg,"||直接打印msg的值")
  22. setTimeout(() => {
  23. //注意数据更新多次,vm._updata(vm._render()) 只需要执行一次
  24. vm.arr.push({b:5})
  25. vm.arr.push({b:6})
  26. console.log(vm.msg,"||计时器打印msg的值")
  27. vm.msg = '张三'
  28. vm.$nextTick(()=>{
  29. console.log(vm.msg,"||nextTick()方法打印msg的值")
  30. })
  31. }, 1000)

 

这里

可以看出来

nextTick()方法中的console确实拿到了最新的值

 

 

2.代码实现

给vm原型添加$nextTick方法

2.1.initState.js

  1. export function stateMixin(vm) {
  2. //列队批处理
  3. //1.处理vue自己的nextTick
  4. //2.用户自己的
  5. vm.prototype.$nextTick = function (cb) {
  6. // console.log(cb)
  7. nextTick(cb)
  8. }
  9. }

 

2.2.watcher.js

(此处为部分代码)

  1. let queue = [] // 将需要批量更新的watcher 存放到一个列队中
  2. let has = {}
  3. let pending = false
  4. //数组重置
  5. function flushWatcher() {
  6. queue.forEach(item => {
  7. item.run()})
  8. queue = []
  9. has = {}
  10. pending = false
  11. }
  12. function queueWatcher(watcher) {
  13. let id = watcher.id // 每个组件都是同一个 watcher
  14. // console.log(id) //去重
  15. if (has[id] == null) {//去重
  16. //列队处理
  17. queue.push(watcher)//将wacher 添加到列队中
  18. has[id] = true
  19. //防抖 :用户触发多次,只触发一个 异步,同步
  20. if (!pending) {
  21. //异步:等待同步代码执行完毕之后,再执行
  22. // setTimeout(()=>{
  23. // queue.forEach(item=>item.run())
  24. // queue = []
  25. // has = {}
  26. // pending = false
  27. // },0)
  28. nextTick(flushWatcher) // nextTick相当于定时器
  29. }
  30. pending = true
  31. }
  32. }

 

2.3.nextTicks.js

  1. let callback = []
  2. let pending = false
  3. function flush(){
  4. callback.forEach(cb =>cb())
  5. pending =false
  6. }
  7. let timerFunc
  8. //处理兼容问题
  9. //判断全局对象中是否存在Promise
  10. //看浏览器是否支持promise
  11. if(Promise){
  12. timerFunc = ()=>{
  13. Promise.resolve().then(flush) //异步处理
  14. }
  15. }else if(MutationObserver){ //h5 异步方法 他可以监听 DOM 变化 ,监控完毕之后在来异步更新
  16. let observe = new MutationObserver(flush)
  17. let textNode = document.createTextNode(1) //创建文本
  18. observe.observe(textNode,{characterData:true}) //观测文本的内容
  19. timerFunc = ()=>{
  20. textNode.textContent = 2
  21. }
  22. }else if(setImmediate){ //ie
  23. timerFunc = ()=>{
  24. setImmediate(flush)
  25. }
  26. }
  27. export function nextTick(cb){
  28. // 1vue 2
  29. // console.log(cb)
  30. //列队 [cb1,cb2]
  31. //此处,注意,我们要处理用户的nextTick()也要处理vue自己的nextTick
  32. callback.push(cb)
  33. //Promise.then() vue3
  34. if(!pending){
  35. timerFunc() //这个方法就是异步方法 但是 处理兼容问题
  36. pending = true
  37. }
  38. }

 

 

 

 

原文链接:https://www.cnblogs.com/FatTiger4399/p/17780739.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号