vue的異步數(shù)據(jù)更新機(jī)制與$nextTick用法解讀
vue異步數(shù)據(jù)更新機(jī)制與$nextTick
vue異步更新dom
vue的響應(yīng)式更新dom是異步執(zhí)行的,不是數(shù)據(jù)發(fā)生變化之后dom立即發(fā)生變化,而是按照一定的邏輯更新dom。
具體是vue在檢測(cè)到數(shù)據(jù)變化時(shí),vue將開啟一個(gè)隊(duì)列,,并緩沖在同一事件循環(huán)中發(fā)生的所有數(shù)據(jù)變更。如果同一個(gè) watcher 被多次觸發(fā),只會(huì)被推入到隊(duì)列中一次。這在緩沖中去除重復(fù)數(shù)據(jù)造成的額外的dom操作和計(jì)算是非常必要的。在下一個(gè)nextTick中,vue執(zhí)行的是已經(jīng)去重的實(shí)際工作。
理解:vue執(zhí)行dom更新時(shí)異步的,這個(gè)異步任務(wù)可以當(dāng)成是一個(gè)promise的微任務(wù),對(duì)同一個(gè)屬性值進(jìn)行多次賦值時(shí),只有最后一次賦值會(huì)作為一個(gè)promise微任務(wù)放到更新隊(duì)列里面。
$nextTick執(zhí)行機(jī)制
Vue會(huì)異步更新DOM,會(huì)在當(dāng)前執(zhí)行棧的最后更新DOM,這個(gè)與JavaScript的原生操作dom有很大區(qū)別。vue中的$nextTick再JavaScript中相當(dāng)于微任務(wù),會(huì)在當(dāng)前所有同步任務(wù)執(zhí)行完之后再執(zhí)行,$nextTick會(huì)得到dom更新后的結(jié)果。最后頁(yè)面渲染是在始終是在微任務(wù)執(zhí)行之后在執(zhí)行的,所以$nextTick回調(diào)執(zhí)行時(shí)還沒(méi)有渲染,頁(yè)面上看不到更新后的結(jié)果。
vue執(zhí)行異步更新的目的
vue更新dom的流程:觸發(fā)setter --> 監(jiān)聽(tīng)watcher --> 重新渲染 render --> 生成虛擬dom (vdom)--> 更新dom 。如果每一次都執(zhí)行該流程會(huì)非常消耗性能,所以使用異步更新DOM的機(jī)制,先對(duì)數(shù)據(jù)修改進(jìn)行整合去重,再使用最終的結(jié)果一次性對(duì)DOM進(jìn)行更新。
vue異步數(shù)據(jù)更新問(wèn)題
記錄一下出現(xiàn)的問(wèn)題, 數(shù)據(jù)翻倍
這是復(fù)現(xiàn)問(wèn)題的代碼
data() { return { space: "", allresult: [] }; }, methods: { getmessage() { this.allresult = []; axios .get( "https://gist.githubusercontent.com/xiaolannuoyi/9b0defe4959e71fa97e6096cc4f82ba4/raw/4be939123d488cee7ecefc055fb5ecb2ed8d5c8d/test" ) .then(data => { console.log(data); let result = data.data; for (let i = 0; i < result.length; i++) { //原因在于這里的this.Allresult this.allresult.push({ id: result[i].id, name: result[i].name, age: result[i].age }); } console.log('此時(shí)的this.allresult',this.allresult); }); } }, watch: { space() { console.log("watch"); this.getmessage(); } }, mounted() { this.space = "123"; console.log("mounted"); this.getmessage(); }
結(jié)果
此時(shí)你可以看到第二次的數(shù)據(jù)時(shí) 是 第一次的 2倍
原因
mounted 和 watch 都執(zhí)行 getmessage 方法,雖然方法之前 對(duì)數(shù)據(jù)進(jìn)行了清空,但是 異步請(qǐng)求執(zhí)行的慢,
所以兩次調(diào)用getmessage相當(dāng)于 this.allresult = []; this.allresult = []; axios...;axios....: 這個(gè)順序
所以才會(huì)出現(xiàn)上述現(xiàn)象
解決
1.修改this.allresult = []
的位置
2.新建一個(gè)臨時(shí)空數(shù)組
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue實(shí)現(xiàn)購(gòu)物車的監(jiān)聽(tīng)
這篇文章主要為大家詳細(xì)介紹了利用vue的監(jiān)聽(tīng)事件實(shí)現(xiàn)一個(gè)簡(jiǎn)單購(gòu)物車,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04TypeScript踩坑之TS7053的問(wèn)題及解決
這篇文章主要介紹了TypeScript踩坑之TS7053的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01解決VUE項(xiàng)目localhost端口服務(wù)器拒絕連接,只能用127.0.0.1的問(wèn)題
這篇文章主要介紹了解決VUE項(xiàng)目localhost端口服務(wù)器拒絕連接,只能用127.0.0.1的問(wèn)題2020-08-08Vue項(xiàng)目保存代碼之后頁(yè)面自動(dòng)更新問(wèn)題
這篇文章主要介紹了Vue項(xiàng)目保存代碼之后頁(yè)面自動(dòng)更新問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10vue項(xiàng)目中js文件使用vue的this實(shí)例說(shuō)明
這篇文章主要介紹了vue項(xiàng)目中js文件使用vue的this實(shí)例說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12Vue組件傳值方式(props屬性,父到子,子到父,兄弟傳值)
這篇文章主要介紹了Vue組件傳值方式(props屬性,父到子,子到父,兄弟傳值),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06Vue中import from@符號(hào)指的是什么意思
這篇文章主要介紹了Vue中import from@符號(hào)指的是意思,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03Vue 列表頁(yè)帶參數(shù)進(jìn)詳情頁(yè)的操作(router-link)
這篇文章主要介紹了Vue 列表頁(yè)帶參數(shù)進(jìn)詳情頁(yè)的操作(router-link),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11