Vue中的nextTick方法是一個(gè)異步方法,它可以讓我們?cè)诋?dāng)前js執(zhí)行棧執(zhí)行完畢后執(zhí)行一個(gè)回調(diào)函數(shù),有點(diǎn)類似setTimeout(fn, 0)。但是與setTimeout不同的是,nextTick會(huì)把回調(diào)函數(shù)放進(jìn)一個(gè)隊(duì)列里,并不會(huì)真正的開啟一個(gè)定時(shí)器去等待執(zhí)行,它是在當(dāng)前js執(zhí)行棧執(zhí)行完畢后去清空這個(gè)隊(duì)列,把回調(diào)函數(shù)依次執(zhí)行。
那么為什么Vue要使用nextTick呢?
我們都知道Vue是一個(gè)響應(yīng)式框架,它通過數(shù)據(jù)驅(qū)動(dòng)視圖的渲染。但是當(dāng)我們改變數(shù)據(jù)時(shí),視圖的渲染并不是實(shí)時(shí)反應(yīng)的,而是在下一個(gè)js執(zhí)行棧里去更新。這就會(huì)出現(xiàn)這樣一個(gè)問題,當(dāng)我們改變數(shù)據(jù)后,立馬去獲取視圖上的某個(gè)元素進(jìn)行操作,有可能會(huì)獲取到錯(cuò)誤的元素,因?yàn)榇藭r(shí)元素還沒有被渲染出來。這時(shí)我們可以使用nextTick方法等到視圖更新完畢后再去獲取操作元素。
Vue.component("example", {
template: ``,
mounted() {
console.log(this.$refs.dom.offsetWidth) //0
//數(shù)據(jù)驅(qū)動(dòng)視圖渲染
this.show = true
this.$nextTick(function() {
console.log(this.$refs.dom.offsetWidth) //100
})
},
data() {
return {
show: false
}
}
})
每次修改數(shù)據(jù)后,我們都可以通過nextTick等待視圖更新完畢,然后去獲取所需的操作元素或者進(jìn)行其他操作。但是如果我們要頻繁使用nextTick,可能會(huì)降低性能,因?yàn)閚extTick會(huì)開啟一個(gè)隊(duì)列去等待執(zhí)行回調(diào)函數(shù)。解決方法就是使用debounce(防抖)去優(yōu)化這個(gè)操作。
mounted(){
console.log(this.$refs.dom.offsetWidth) //0
//防抖函數(shù)
let handle = (function(){
let timer = null
return (cb)=>{
if(timer) clearTimeout(timer)
timer = setTimeout(()=>{
Promise.resolve().then(cb)
}, 0)
}
})()
//修改數(shù)據(jù)
this.show = true
handle(()=>{
console.log(this.$refs.dom.offsetWidth)
})
}
以上就是Vue中nextTick的使用方法及優(yōu)化方式,它可以讓我們高效的等待視圖更新完畢后進(jìn)行下一步操作,提高代碼的穩(wěn)定性及可讀性。