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ù)后視圖沒有更新。
排查
這個問題很奇怪,因為之前在公司的時候,代碼明明是沒有問題的,當(dāng)時我以為可能是自己不小心改了什么代碼,出bug了。當(dāng)然我心里一點都不慌,數(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é)果瀏覽器插件就幫我對頁面進行了翻譯,當(dāng)然我的頁面本身就是中文,我并沒有看出異常。但是這個時候的頁面已經(jīng)是翻譯的頁面了,我dom的變化這個翻譯的頁面是不會同步的。所以就導(dǎo)致了我所看到的數(shù)據(jù)沒有刷新的問題。
發(fā)現(xiàn)真相的時候我的內(nèi)心是崩潰的,搞了這么就原因竟然是這個。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue-resourse將json數(shù)據(jù)輸出實例
這篇文章主要為大家詳細介紹了vue-resourse將json數(shù)據(jù)輸出實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03深入探究Vue2響應(yīng)式原理的實現(xiàn)及存在的缺陷
Vue的響應(yīng)式數(shù)據(jù)機制是其核心特性之一,它能夠自動追蹤數(shù)據(jù)的變化,并實時更新相關(guān)的視圖,然而,Vue2中的響應(yīng)式數(shù)據(jù)機制并非完美無缺,本文將探討Vue2響應(yīng)式原理及其存在的缺陷2023-08-08vue-cli 引入jQuery,Bootstrap,popper的方法
這篇文章主要介紹了vue-cli 引入jQuery,Bootstrap,popper的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-09-09使用iView Upload 組件實現(xiàn)手動上傳圖片的示例代碼
這篇文章主要介紹了使用iView Upload 組件實現(xiàn)手動上傳圖片的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-10-10