这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战
因为热爱所以坚持~
前言
xdm,连载我的故事哈哈~ 同事离职,被迫接手一个长期维护型项目,天天都很崩溃,做梦都是相关内容,于是今天跟组长提了不想干这个项目了,进而萌生提桶的想法。但是前辈特别好,希望我可以坚持坚持,我也确实不想辜负他的好意,就再待两天看看吧!今天学this.$nextTick(),项目代码中看到过好多次,一直没研究,正好学一下~
nextTick()
定义: 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM
使用:
import { createApp, nextTick } from 'vue'
const app = createApp({
setup() {
const message = ref('Hello!')
const changeMessage = async newMessage => {
message.value = newMessage
// 这里获取DOM的value是旧值
await nextTick()
// nextTick 后获取DOM的value是更新后的值
console.log('Now DOM is updated')
}
}
})
JS执行机制:单线程,同步异步,来自:vue3js.cn/global/next…
- (1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
- (2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
- (3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
- (4)主线程不断重复上面的第三步
vue 里的nextTick() 基于语言执行机制实现,直接创建一个异步任务,那么nextTick自然就达到在同步任务后执行的目的:
const p = Promise.resolve()
export function nextTick(fn?: () => void): Promise<void> {
return fn ? p.then(fn) : p
}
官网上接下来在分析源码,好复杂~总的来说应该是:nextTick(),是将回调函数延迟在下一次dom更新数据后调用,也就是:当数据更新了,在dom中渲染后,自动执行该函数。
举例
<div @click="changeMsg() ref="test">{{message}}</div>
<script>
export default{
data(){
return{
message:"origin"
}
},
methods:{
//没有用nextTick()
changeMsg:function(){
let _this = this;
_this.message = "now";
console.log(_this.$ref.test.innerText)//输出origin(this.$ref.test取指定DOM)
},
//使用了nextTick()
changeMsg:function(){
let _this = this;
_this.message = "now";
_this.nextTick(function(){
console.log(_this.$ref.test.innerText)//输出now
});
}
}
}
</script>
总结:vue实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。nextTick,则可以在回调中获取更新后的 DOM。