這篇文章主要介紹了vue是異步渲染的原因有哪些的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇vue是異步渲染的原因有哪些文章都會(huì)有所收獲,下面我們一起來看看吧。
創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括革吉網(wǎng)站建設(shè)、革吉網(wǎng)站制作、革吉網(wǎng)頁制作以及革吉網(wǎng)絡(luò)營(yíng)銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,革吉網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到革吉省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
原因:可以提升性能。如果不采用異步更新,那么每次更新數(shù)據(jù)都會(huì)對(duì)當(dāng)前組件進(jìn)行重新渲染;所以為了性能考慮,Vue會(huì)在本輪數(shù)據(jù)更新后,再去異步更新視圖,而不是每當(dāng)有數(shù)據(jù)更新,就立即更新視圖。
nextTick確保我們所操作的DOM是更新之后的。
(1)應(yīng)用場(chǎng)景:在視圖更新之后,基于新的視圖進(jìn)行操作。
在數(shù)據(jù)變化后執(zhí)行的某個(gè)操作,而這個(gè)操作需要使用隨數(shù)據(jù)變化而變化的DOM結(jié)構(gòu)的時(shí)候,這個(gè)操作就需要放在nextTick()
的回調(diào)函數(shù)中。
如果在created()鉤子進(jìn)行DOM操作,created()中dom還沒有渲染,一定要放在nextTick()
的回調(diào)函數(shù)中。
Vue采用了數(shù)據(jù)驅(qū)動(dòng)視圖的思想,但是在一些情況下,仍然需要操作DOM。有時(shí)候,DOM1的數(shù)據(jù)發(fā)生了變化,而DOM2需要從DOM1中獲取數(shù)據(jù),那這時(shí)就會(huì)發(fā)現(xiàn)DOM2的視圖并沒有更新,這時(shí)就需要用到了nextTick
了。
(2)原理:
nextTick 的核心是利用了如 Promise 、MutationObserver、setImmediate、setTimeout的原生 JS 方法來模擬對(duì)應(yīng)的微/宏任務(wù)的實(shí)現(xiàn);
本質(zhì)是為了利用 JS的這些異步回調(diào)任務(wù)隊(duì)列來實(shí)現(xiàn) Vue 框架中自己的異步回調(diào)隊(duì)列;
本質(zhì)是對(duì)JS執(zhí)行原理事件循環(huán)的一種應(yīng)用
nextTick 是典型的將底層JS執(zhí)行原理應(yīng)用到具體案例中的示例,引入異步更新隊(duì)列機(jī)制的原因∶
如果不采用異步更新,那么每次更新數(shù)據(jù)都會(huì)對(duì)當(dāng)前組件進(jìn)行重新渲染。所以為了性能考慮,Vue 會(huì)在本輪數(shù)據(jù)更新后,再去異步更新視圖。而不是每當(dāng)有數(shù)據(jù)更新,就立即更新視圖。
為了在數(shù)據(jù)更新操作之后操作DOM,我們可以在數(shù)據(jù)變化之后立即使用nextTick(callback)
;
nextTick()將回調(diào)延遲到下一個(gè)事件循環(huán)開始時(shí)執(zhí)行, 這樣回調(diào)函數(shù)會(huì)在DOM更新完成后被調(diào)用,就可以拿到最新的DOM元素了。
當(dāng)你設(shè)置 vm.someData = 'new value',DOM 并不會(huì)馬上更新,而是在異步隊(duì)列被清除,也就是下一個(gè)事件循環(huán)開始時(shí)執(zhí)行更新才會(huì)進(jìn)行必要的DOM更新。
(3) vue的降級(jí)策略
Vue 在內(nèi)部對(duì)異步隊(duì)列嘗試使用原生的 Promise.then、MutationObserver和 setImmediate,如果執(zhí)行環(huán)境不支持,則會(huì)采用 setTimeout(fn, 0)代替,進(jìn)行降級(jí)處理。降級(jí)處理的目的都是將flushCallbacks
函數(shù)放入微任務(wù)或者宏任務(wù)隊(duì)列,等待下一次事件循環(huán)時(shí)來執(zhí)行
實(shí)際刷新隊(duì)列是有可能在本次事件循環(huán)的微任務(wù)中刷新的,也可能是在下一個(gè)事件循環(huán)中刷新的。這取決于代碼當(dāng)前執(zhí)行的環(huán)境,如若當(dāng)前執(zhí)行環(huán)境支持promise,那么nextTick內(nèi)部實(shí)際會(huì)用Promise去執(zhí)行,那么隊(duì)列刷新就會(huì)在本次事件循環(huán)的微任務(wù)中去執(zhí)行。
優(yōu)先選擇微任務(wù)的原因:在微任務(wù)中更新隊(duì)列是會(huì)比在宏任務(wù)中更新少一次UI渲染的。
vue是組件級(jí)更新,組件內(nèi)有數(shù)據(jù)變化時(shí),該組件就會(huì)更新。例:this.a = 1、this.b=2(同一個(gè)watcher)
(1)原因:如果不采用異步更新,那么每次更新數(shù)據(jù)都會(huì)對(duì)當(dāng)前組件進(jìn)行重新渲染。所以為了性能考慮,Vue 會(huì)在本輪數(shù)據(jù)更新后,再去異步更新視圖。而不是每當(dāng)有數(shù)據(jù)更新,就立即更新視圖。
(2)過程:
Vue是異步執(zhí)行dom更新的,一旦觀察到數(shù)據(jù)變化,Vue就會(huì)開啟一個(gè)隊(duì)列,然后把在同一個(gè)事件循環(huán) (event loop) 中 觀察到數(shù)據(jù)變化的 watcher 推送進(jìn)這個(gè)隊(duì)列。
如果這個(gè)watcher被觸發(fā)多次,只會(huì)被推送到隊(duì)列一次。這種緩沖行為可以有效的去掉重復(fù)數(shù)據(jù),避免不必要的計(jì)算和Dom操作。
而在下一個(gè)事件循環(huán)時(shí),Vue會(huì)清空隊(duì)列,并進(jìn)行必要的DOM更新。
3)源碼解析:
數(shù)據(jù)變化時(shí),通過notify通知watcher進(jìn)行更新操作;
通過subs[i].update依次調(diào)用watcher的update(未更新視圖);
將watcher放到隊(duì)列中,在queueWatcher會(huì)根據(jù)watcher的id進(jìn)行去重(多個(gè)屬性依賴一個(gè)watcher),如果隊(duì)列中沒有該watcher就會(huì)將該watcher添加到隊(duì)列中(未更新視圖);
通過nextTick異步執(zhí)行flushSchedulerQueue方法刷新watcher隊(duì)列(更新視圖);
關(guān)于“vue是異步渲染的原因有哪些”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“vue是異步渲染的原因有哪些”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。