Vue2面試考點(diǎn)之$nextTick原理解析
nextTick原理
平時(shí)在獲取真實(shí)DOM的時(shí)候獲取不到最新的DOM元素,使用$nextTick就可以
為什么$nextTick就可以獲取到最新的DOM元素?
帶著以上問(wèn)題,來(lái)解析nextTick的原理
為什么獲取不到最新的DOM元素
因?yàn)閂ue修改視圖是異步執(zhí)行的,這也是為了優(yōu)化性能,在我們修改data中的數(shù)據(jù)時(shí),Vue內(nèi)部監(jiān)聽(tīng)到依賴(lài)數(shù)據(jù)發(fā)生了改變,通過(guò)dep通知組件的watcher執(zhí)行視圖更新,每一次視圖更新都需要重新生成vnode再進(jìn)行新舊vnode比對(duì),生成DOM元素掛載到頁(yè)面上,這一輪操作是非常消耗性能的,所以Vue內(nèi)部會(huì)把頁(yè)面更新watcher推入到一個(gè)隊(duì)列中,并加入了節(jié)流方法,當(dāng)同步代碼執(zhí)行完了之后才會(huì)把隊(duì)列中的watcher拿出來(lái)遍歷更新視圖,我們?cè)谑褂胻his.$refs獲取DOM的時(shí)候是同步代碼,其實(shí)DOM還沒(méi)有更新,所以是獲取不到的
為什么使用$nextTick就可以獲取到最新DOM
Vue的視圖更新是異步執(zhí)行的,使用的就是nextTick,這也是能獲取到最新DOM的原因,在Vue內(nèi)部有一個(gè)nextTick函數(shù),他也是使用隊(duì)列去處理回調(diào)函數(shù),并不是調(diào)用后就馬上執(zhí)行,首先是推入到一個(gè)隊(duì)列中,當(dāng)所有的同步代碼執(zhí)行完的時(shí)候再通過(guò)循環(huán)取出調(diào)用,接下來(lái)可以通過(guò)代碼了解
let callback = []
let pending = false
let timerFunc
function flush() {
callback.forEach((cb) => cb())
pending = false
callback = []
}
// 處理兼容問(wèn)題
if (Promise) {
timerFunc = () => {
Promise.resolve().then(flush)
}
} else if (MutationObserver) {
let observe = new MutationObserver(flush)
let textNode = document.createTextNode(1)
observe.observe(textNode, {
characterData: true,
})
timerFunc = () => {
textNode.textContent = 2
}
} else if (setImmediate) {
// ie瀏覽器支持得定時(shí)器
timerFunc = () => {
setImmediate(flush)
}
}
export function nextTick(cb) {
callback.push(cb)
// Promise.then
if (!pending) {
console.log('執(zhí)行了')
timerFunc() // 這個(gè)方法就是異步方法
pending = true
}
}
1.定義一個(gè)callback數(shù)組,每次調(diào)用nextTick就會(huì)把回調(diào)函數(shù)push到callback數(shù)組中,因?yàn)閏allback.push是同步代碼,timerFunc是異步代碼,所以執(zhí)行完所有push后才會(huì)調(diào)用timerFunc
2.那么視圖更新和獲取DOM的流程是怎么樣的呢
通過(guò)偽代碼來(lái)解釋
data(){
return {
name: 'zs',
list: [1,2,3]
}
}
this.name = 'ls'
this.list.push(4)
const fn = () => {
this.$el.innerHTML // 獲取最新DOM
}
this.$nextTick(fn)this.name和this.list修改了2個(gè)數(shù)據(jù),會(huì)觸發(fā)兩次視圖更新,這個(gè)時(shí)候就會(huì)把watcher推入到隊(duì)列中,下面調(diào)用了$nextTick獲取DOM,nextTick中的fn函數(shù)也會(huì)推入到隊(duì)列中,這個(gè)時(shí)候的數(shù)組是這樣的[watcher,fn]通過(guò)循環(huán)調(diào)用,先執(zhí)行視圖更新,后獲取DOM就可以獲取到最新DOM了
到此這篇關(guān)于Vue2面試考點(diǎn)之$nextTick原理解析的文章就介紹到這了,更多相關(guān)Vue2 $nextTick內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue?background-image?不顯示問(wèn)題的解決
這篇文章主要介紹了vue?background-image?不顯示問(wèn)題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
vue3中通過(guò)ref獲取元素節(jié)點(diǎn)的實(shí)現(xiàn)
這篇文章主要介紹了vue3中通過(guò)ref獲取元素節(jié)點(diǎn)的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
如何利用vue3實(shí)現(xiàn)一個(gè)俄羅斯方塊
俄羅斯方塊這個(gè)游戲相信大家都玩過(guò),下面這篇文章主要給大家介紹了關(guān)于如何利用vue3實(shí)現(xiàn)一個(gè)俄羅斯方塊的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-01-01
vue watch關(guān)于對(duì)象內(nèi)的屬性監(jiān)聽(tīng)
這篇文章主要介紹了vue watch關(guān)于對(duì)象內(nèi)的屬性監(jiān)聽(tīng)的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-04-04
Vue中$nextTick實(shí)現(xiàn)源碼解析
這篇文章主要為大家介紹了Vue中$nextTick實(shí)現(xiàn)源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
Vue.js 利用v-for中的index值實(shí)現(xiàn)隔行變色
這篇文章主要介紹了Vue.js 利用v-for中的index值實(shí)現(xiàn)隔行變色效果,首先定義好樣式,利用v-for中的index值,然后綁定樣式來(lái)實(shí)現(xiàn)隔行變色,需要的朋友可以參考下2018-08-08
vue2基本響應(yīng)式實(shí)現(xiàn)方式之讓數(shù)組也變成響應(yīng)式
這篇文章主要介紹了vue2基本響應(yīng)式實(shí)現(xiàn)方式之讓數(shù)組也變成響應(yīng)式問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
詳解vue 單頁(yè)應(yīng)用(spa)前端路由實(shí)現(xiàn)原理
這篇文章主要介紹了詳解vue 單頁(yè)應(yīng)用(spa)前端路由實(shí)現(xiàn)原理,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04

