Vue3數(shù)據(jù)更新,頁面沒有同步更新的問題及解決
數(shù)據(jù)更新,頁面沒有同步更新
情景
頁面中的列表需要渲染接口返回的數(shù)據(jù)
問題
根據(jù)控制臺中打印的結(jié)果來看,接口數(shù)據(jù)請求且存儲成功,但是頁面列表中仍無數(shù)據(jù),且控制臺中無報錯
解決方法
剛開始是將接口數(shù)據(jù)直接存儲在數(shù)組中的,在網(wǎng)上查找了相關(guān)問題后,將數(shù)組包裹在一個響應(yīng)式對象中
如下圖所示,問題成功解決,暫時不明白其中原理。

數(shù)據(jù)不同步的排查記錄
我遇到了一個vue異步獲取數(shù)據(jù)后視圖沒有更新的問題,排查了很久很久,最后才發(fā)現(xiàn)自己踩在了一個自己萬萬沒有想到的坑上,所以記錄一下。
常見的解決方案
關(guān)于vue數(shù)據(jù)不同步的排查已經(jīng)有很多類似的博客了,一般而言,原因有一下幾點:
- 數(shù)據(jù)沒有設(shè)置成功
- 設(shè)置的數(shù)據(jù)不是響應(yīng)式的
- 設(shè)置的數(shù)據(jù)和視圖上的變量不是同一個,可能設(shè)置錯了變量
既然寫到類似話題,我也羅列一下相關(guān)的解決方案:
使用this.$set(),
可以嘗試類似this.data=JSON.parse(JSON.stringify(data))去排查是不是數(shù)據(jù)劫持的問題。
這個我一個同事遇到過一次,他發(fā)現(xiàn)他的變量里面部分屬性沒有設(shè)置get/set(就是沒有被vue監(jiān)聽到,所以無法響應(yīng)式),原因大概是他在原變量上加了新屬性,但是沒有被vue監(jiān)聽到。這是一個很有迷惑性的例子,
大家可以看看下面的代碼:
這里其實是希望屬性b可以被監(jiān)聽到的,所以嘗試重新給this.data賦值,但是很遺憾,const data的引用和this.data是同一個,this.data = data并不能實現(xiàn)變量的覆蓋(因為vue只有變量和之前不同才會對變量里面的所有屬性做劫持,同一個引用,vue不會對新屬性進行監(jiān)聽)
// 例子
// 假設(shè)已經(jīng)有一個data
{
data(){
return {
data:[{a:1}]
}
},
created(){
/* 在這里其實我們是希望將變量覆蓋的 */
const data = this.data
data[0].b = 1
this.data = data
}
}
可以看大以下輸出,可以看到a屬性是有g(shù)et和set的,即他們已經(jīng)是響應(yīng)式的了,但是b卻沒有g(shù)et/set。
使用this.data=JSON.parse(JSON.stringify(data))的原理實際上就是為了創(chuàng)建一個新的對象重新賦值。

- 如果還是不行,要仔細檢查變量有沒有設(shè)置成功,可以通過vue的Devtools工具查看,或者直接輸出到控制臺里面查看。有可能是this等的指向不對或者是拼寫錯誤導(dǎo)致變量賦值失敗
- 還要看看視圖里面的變量和你所希望更新的變量是不是同一個,會不會是視圖里面的變量寫錯了
- 其他的方法還包括:重啟以下瀏覽器,看看是不是瀏覽器本身異常了等。
接下來,就是我個人的比較獨特的問題了,如果你還沒有解決,或者好奇我遇到的是一個怎樣的問題,你也可以往下讀。
問題描述
在chrome瀏覽器上開發(fā)vue項目,結(jié)果突然發(fā)現(xiàn)異步獲取數(shù)據(jù)后視圖沒有更新。
排查
這個問題很奇怪,因為之前在公司的時候,代碼明明是沒有問題的,當時我以為可能是自己不小心改了什么代碼,出bug了。當然我心里一點都不慌,數(shù)據(jù)沒有更新嘛,一般原因有以下幾點:
- 數(shù)據(jù)沒有設(shè)置成功
- 設(shè)置的數(shù)據(jù)不是響應(yīng)式的
- 設(shè)置的數(shù)據(jù)和視圖上的變量不是同一個,可能設(shè)置錯了變量
結(jié)果!??!竟然不是這些原因,我通過vue的Devtools工具查看,發(fā)現(xiàn)數(shù)據(jù)正確設(shè)置了,而且是響應(yīng)式的,可以動態(tài)更新。
我不放心,又通過debugger打斷點,并輸出了相應(yīng)的data到控制臺上,結(jié)果確認我所希望使用的變量確實已經(jīng)被vue進行了劫持(vue2的響應(yīng)式其實就是通過Object.defineProperty對數(shù)據(jù)進行監(jiān)聽)
我隨便mock了一個數(shù)據(jù)截圖如下:如果一個變量屬性是響應(yīng)式的,那它應(yīng)該會多出了下圖中框住的get/set。

由此我確認了我的數(shù)據(jù)是響應(yīng)式的,我又再三確認了視圖的變量沒有問題。這時,我開始慌了,感覺自己可能掉進了一個不好排查的坑里面出不來了。果然,我嘗試了各種辦法,卻始終無法解決這個問題。期間我也試了各種各樣的手段去搜索,始終一無所獲。
直到我試著在360瀏覽器上打開這個頁面,發(fā)現(xiàn)頁面的數(shù)據(jù)竟然可以動態(tài)刷新?。?!這時我反應(yīng)過來,難道是瀏覽器的兼容問題,或者是瀏覽器本身異常?
我又試著重啟chrome瀏覽器,發(fā)現(xiàn)還是不行。
難道真的是兼容問題嗎?但是沒有理由的呀,之前在公司明明是正常的,難道還和瀏覽器版本有關(guān)系?這時我開始想這個數(shù)據(jù)和普通的數(shù)據(jù)有什么不同,一個明顯的不同是這個數(shù)據(jù)嵌套比較深?不會吧,數(shù)據(jù)嵌套太深會導(dǎo)致數(shù)據(jù)無法同步的嗎?
說實話,我糾結(jié)了很久,最后是真的無意間發(fā)現(xiàn)了真相:
真相
導(dǎo)致我數(shù)據(jù)無法同步的真兇竟然是Google 翻譯這個插件。。。
真相是這樣的,我對頁面頭部寫了<html lang="en">結(jié)果瀏覽器插件就幫我對頁面進行了翻譯,當然我的頁面本身就是中文,我并沒有看出異常。但是這個時候的頁面已經(jīng)是翻譯的頁面了,我dom的變化這個翻譯的頁面是不會同步的。所以就導(dǎo)致了我所看到的數(shù)據(jù)沒有刷新的問題。
發(fā)現(xiàn)真相的時候我的內(nèi)心是崩潰的,搞了這么就原因竟然是這個。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
基于electron+vue3+ts搭建桌面端應(yīng)用并且可以熱更新
這篇文章主要為大家詳細介紹了如何基于electron+vue3+ts搭建桌面端應(yīng)用并且可以熱更新,文中的示例代碼講解詳細,感興趣的小伙伴可以參考下2023-10-10
vue3 學(xué)習(xí)筆記之a(chǎn)xios的使用變化總結(jié)
本篇文章主要旨在幫助正在學(xué)vue3或者準備學(xué)vue3的同學(xué)了解網(wǎng)絡(luò)請求axios該如何使用,防止接觸了一點點vue3的同學(xué)會有個疑問。有興趣的小伙伴可以關(guān)注一下2021-11-11
Vue時間軸 vue-light-timeline的用法說明
這篇文章主要介紹了Vue時間軸 vue-light-timeline的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
Vue如何使用Element-ui表單發(fā)送數(shù)據(jù)與多張圖片到后端詳解
在做項目的時候遇到一個問題,前端需要上傳表單到后端,表單數(shù)據(jù)包括文本內(nèi)容和圖片,這篇文章主要給大家介紹了關(guān)于Vue如何使用Element-ui表單發(fā)送數(shù)據(jù)與多張圖片到后端的相關(guān)資料,需要的朋友可以參考下2022-04-04
vue cli3 實現(xiàn)分環(huán)境打包的步驟
這篇文章主要介紹了vue cli3 實現(xiàn)分環(huán)境打包的步驟,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03

