好家伙,nextTick,
(...这玩意,不太常用)
1.什么是nextTick
在Vue中,nextTick是一个用于异步执行回调函数的方法。
它在Vue更新DOM后被调用,以确保在下一次DOM更新渲染完成后执行回调函数。
而事实上,我们把队列处理的操作封装到了nexrTick方法中.
实际上,Vue在更新DOM时是异步执行的。
当你修改Vue实例的数据时,Vue会对依赖这些数据的虚拟DOM进行重新渲染,然后更新到真实的DOM上。
但是,DOM更新是在下一个事件循环中执行的,而不是立即执行。
所以,如果你想在DOM更新后执行一些操作,你就可以使用nextTick方法。
这个方法会将回调函数推入到微任务队列中,并在DOM更新后执行。
这样可以确保你在操作更新后的DOM,比如获取元素的宽高等,而不是得到修改前的值。
举一个非常简单的例子
Vue.Mixin({ //全局 created: function b() { // console.log('b----2') } }) let vm = new Vue({ el: '#app', //编译模板 // data: { // }, data() { // console.log(this) return { msg:'牛肉', arr: [1, 2, 3], } }, created() { // console.log(555) } }) console.log(vm.msg,"||直接打印msg的值") setTimeout(() => { //注意数据更新多次,vm._updata(vm._render()) 只需要执行一次 vm.arr.push({b:5}) vm.arr.push({b:6}) console.log(vm.msg,"||计时器打印msg的值") vm.msg = '张三' vm.$nextTick(()=>{ console.log(vm.msg,"||nextTick()方法打印msg的值") }) }, 1000)
这里
可以看出来
nextTick()方法中的console确实拿到了最新的值
2.代码实现
给vm原型添加$nextTick方法
2.1.initState.js
export function stateMixin(vm) { //列队批处理 //1.处理vue自己的nextTick //2.用户自己的 vm.prototype.$nextTick = function (cb) { // console.log(cb) nextTick(cb) } }
2.2.watcher.js
(此处为部分代码)
let queue = [] // 将需要批量更新的watcher 存放到一个列队中 let has = {} let pending = false //数组重置 function flushWatcher() { queue.forEach(item => { item.run()}) queue = [] has = {} pending = false } function queueWatcher(watcher) { let id = watcher.id // 每个组件都是同一个 watcher // console.log(id) //去重 if (has[id] == null) {//去重 //列队处理 queue.push(watcher)//将wacher 添加到列队中 has[id] = true //防抖 :用户触发多次,只触发一个 异步,同步 if (!pending) { //异步:等待同步代码执行完毕之后,再执行 // setTimeout(()=>{ // queue.forEach(item=>item.run()) // queue = [] // has = {} // pending = false // },0) nextTick(flushWatcher) // nextTick相当于定时器 } pending = true } }
2.3.nextTicks.js
let callback = [] let pending = false function flush(){ callback.forEach(cb =>cb()) pending =false } let timerFunc //处理兼容问题 //判断全局对象中是否存在Promise //看浏览器是否支持promise if(Promise){ timerFunc = ()=>{ Promise.resolve().then(flush) //异步处理 } }else if(MutationObserver){ //h5 异步方法 他可以监听 DOM 变化 ,监控完毕之后在来异步更新 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){ // 1vue 2 // console.log(cb) //列队 [cb1,cb2] //此处,注意,我们要处理用户的nextTick()也要处理vue自己的nextTick callback.push(cb) //Promise.then() vue3 if(!pending){ timerFunc() //这个方法就是异步方法 但是 处理兼容问题 pending = true } }
标签:nextTick,Vue,console,DOM,vm,源码,let,pending From: https://www.cnblogs.com/FatTiger4399/p/17780739.html