Vue3數(shù)據(jù)更新,頁(yè)面沒(méi)有同步更新的問(wèn)題及解決
數(shù)據(jù)更新,頁(yè)面沒(méi)有同步更新
情景
頁(yè)面中的列表需要渲染接口返回的數(shù)據(jù)
問(wèn)題
根據(jù)控制臺(tái)中打印的結(jié)果來(lái)看,接口數(shù)據(jù)請(qǐng)求且存儲(chǔ)成功,但是頁(yè)面列表中仍無(wú)數(shù)據(jù),且控制臺(tái)中無(wú)報(bào)錯(cuò)
解決方法
剛開始是將接口數(shù)據(jù)直接存儲(chǔ)在數(shù)組中的,在網(wǎng)上查找了相關(guān)問(wèn)題后,將數(shù)組包裹在一個(gè)響應(yīng)式對(duì)象中
如下圖所示,問(wèn)題成功解決,暫時(shí)不明白其中原理。
數(shù)據(jù)不同步的排查記錄
我遇到了一個(gè)vue異步獲取數(shù)據(jù)后視圖沒(méi)有更新的問(wèn)題,排查了很久很久,最后才發(fā)現(xiàn)自己踩在了一個(gè)自己萬(wàn)萬(wàn)沒(méi)有想到的坑上,所以記錄一下。
常見的解決方案
關(guān)于vue數(shù)據(jù)不同步的排查已經(jīng)有很多類似的博客了,一般而言,原因有一下幾點(diǎn):
- 數(shù)據(jù)沒(méi)有設(shè)置成功
- 設(shè)置的數(shù)據(jù)不是響應(yīng)式的
- 設(shè)置的數(shù)據(jù)和視圖上的變量不是同一個(gè),可能設(shè)置錯(cuò)了變量
既然寫到類似話題,我也羅列一下相關(guān)的解決方案:
使用this.$set()
,
可以嘗試類似this.data=JSON.parse(JSON.stringify(data))
去排查是不是數(shù)據(jù)劫持的問(wèn)題。
這個(gè)我一個(gè)同事遇到過(guò)一次,他發(fā)現(xiàn)他的變量里面部分屬性沒(méi)有設(shè)置get/set(就是沒(méi)有被vue監(jiān)聽到,所以無(wú)法響應(yīng)式),原因大概是他在原變量上加了新屬性,但是沒(méi)有被vue監(jiān)聽到。這是一個(gè)很有迷惑性的例子,
大家可以看看下面的代碼:
這里其實(shí)是希望屬性b可以被監(jiān)聽到的,所以嘗試重新給this.data賦值,但是很遺憾,const data
的引用和this.data
是同一個(gè),this.data = data
并不能實(shí)現(xiàn)變量的覆蓋(因?yàn)関ue只有變量和之前不同才會(huì)對(duì)變量里面的所有屬性做劫持,同一個(gè)引用,vue不會(huì)對(duì)新屬性進(jìn)行監(jiān)聽)
// 例子 // 假設(shè)已經(jīng)有一個(gè)data { data(){ return { data:[{a:1}] } }, created(){ /* 在這里其實(shí)我們是希望將變量覆蓋的 */ const data = this.data data[0].b = 1 this.data = data } }
可以看大以下輸出,可以看到a屬性是有g(shù)et和set的,即他們已經(jīng)是響應(yīng)式的了,但是b卻沒(méi)有g(shù)et/set。
使用this.data=JSON.parse(JSON.stringify(data))
的原理實(shí)際上就是為了創(chuàng)建一個(gè)新的對(duì)象重新賦值。
- 如果還是不行,要仔細(xì)檢查變量有沒(méi)有設(shè)置成功,可以通過(guò)vue的Devtools工具查看,或者直接輸出到控制臺(tái)里面查看。有可能是this等的指向不對(duì)或者是拼寫錯(cuò)誤導(dǎo)致變量賦值失敗
- 還要看看視圖里面的變量和你所希望更新的變量是不是同一個(gè),會(huì)不會(huì)是視圖里面的變量寫錯(cuò)了
- 其他的方法還包括:重啟以下瀏覽器,看看是不是瀏覽器本身異常了等。
接下來(lái),就是我個(gè)人的比較獨(dú)特的問(wèn)題了,如果你還沒(méi)有解決,或者好奇我遇到的是一個(gè)怎樣的問(wèn)題,你也可以往下讀。
問(wèn)題描述
在chrome瀏覽器上開發(fā)vue項(xiàng)目,結(jié)果突然發(fā)現(xiàn)異步獲取數(shù)據(jù)后視圖沒(méi)有更新。
排查
這個(gè)問(wèn)題很奇怪,因?yàn)橹霸诠镜臅r(shí)候,代碼明明是沒(méi)有問(wèn)題的,當(dāng)時(shí)我以為可能是自己不小心改了什么代碼,出bug了。當(dāng)然我心里一點(diǎn)都不慌,數(shù)據(jù)沒(méi)有更新嘛,一般原因有以下幾點(diǎn):
- 數(shù)據(jù)沒(méi)有設(shè)置成功
- 設(shè)置的數(shù)據(jù)不是響應(yīng)式的
- 設(shè)置的數(shù)據(jù)和視圖上的變量不是同一個(gè),可能設(shè)置錯(cuò)了變量
結(jié)果?。?!竟然不是這些原因,我通過(guò)vue的Devtools工具查看,發(fā)現(xiàn)數(shù)據(jù)正確設(shè)置了,而且是響應(yīng)式的,可以動(dòng)態(tài)更新。
我不放心,又通過(guò)debugger打斷點(diǎn),并輸出了相應(yīng)的data到控制臺(tái)上,結(jié)果確認(rèn)我所希望使用的變量確實(shí)已經(jīng)被vue進(jìn)行了劫持(vue2的響應(yīng)式其實(shí)就是通過(guò)Object.defineProperty對(duì)數(shù)據(jù)進(jìn)行監(jiān)聽)
我隨便mock了一個(gè)數(shù)據(jù)截圖如下:如果一個(gè)變量屬性是響應(yīng)式的,那它應(yīng)該會(huì)多出了下圖中框住的get/set。
由此我確認(rèn)了我的數(shù)據(jù)是響應(yīng)式的,我又再三確認(rèn)了視圖的變量沒(méi)有問(wèn)題。這時(shí),我開始慌了,感覺(jué)自己可能掉進(jìn)了一個(gè)不好排查的坑里面出不來(lái)了。果然,我嘗試了各種辦法,卻始終無(wú)法解決這個(gè)問(wèn)題。期間我也試了各種各樣的手段去搜索,始終一無(wú)所獲。
直到我試著在360瀏覽器上打開這個(gè)頁(yè)面,發(fā)現(xiàn)頁(yè)面的數(shù)據(jù)竟然可以動(dòng)態(tài)刷新?。?!這時(shí)我反應(yīng)過(guò)來(lái),難道是瀏覽器的兼容問(wèn)題,或者是瀏覽器本身異常?
我又試著重啟chrome瀏覽器,發(fā)現(xiàn)還是不行。
難道真的是兼容問(wèn)題嗎?但是沒(méi)有理由的呀,之前在公司明明是正常的,難道還和瀏覽器版本有關(guān)系?這時(shí)我開始想這個(gè)數(shù)據(jù)和普通的數(shù)據(jù)有什么不同,一個(gè)明顯的不同是這個(gè)數(shù)據(jù)嵌套比較深?不會(huì)吧,數(shù)據(jù)嵌套太深會(huì)導(dǎo)致數(shù)據(jù)無(wú)法同步的嗎?
說(shuō)實(shí)話,我糾結(jié)了很久,最后是真的無(wú)意間發(fā)現(xiàn)了真相:
真相
導(dǎo)致我數(shù)據(jù)無(wú)法同步的真兇竟然是Google 翻譯
這個(gè)插件。。。
真相是這樣的,我對(duì)頁(yè)面頭部寫了<html lang="en">
結(jié)果瀏覽器插件就幫我對(duì)頁(yè)面進(jìn)行了翻譯,當(dāng)然我的頁(yè)面本身就是中文,我并沒(méi)有看出異常。但是這個(gè)時(shí)候的頁(yè)面已經(jīng)是翻譯的頁(yè)面了,我dom的變化這個(gè)翻譯的頁(yè)面是不會(huì)同步的。所以就導(dǎo)致了我所看到的數(shù)據(jù)沒(méi)有刷新的問(wèn)題。
發(fā)現(xiàn)真相的時(shí)候我的內(nèi)心是崩潰的,搞了這么就原因竟然是這個(gè)。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue-resourse將json數(shù)據(jù)輸出實(shí)例
這篇文章主要為大家詳細(xì)介紹了vue-resourse將json數(shù)據(jù)輸出實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03深入探究Vue2響應(yīng)式原理的實(shí)現(xiàn)及存在的缺陷
Vue的響應(yīng)式數(shù)據(jù)機(jī)制是其核心特性之一,它能夠自動(dòng)追蹤數(shù)據(jù)的變化,并實(shí)時(shí)更新相關(guān)的視圖,然而,Vue2中的響應(yīng)式數(shù)據(jù)機(jī)制并非完美無(wú)缺,本文將探討Vue2響應(yīng)式原理及其存在的缺陷2023-08-08el-date-picker日期范圍限制的實(shí)現(xiàn)
本文主要介紹了el-date-picker日期范圍限制的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05十個(gè)有用的自定義Vue鉤子函數(shù)總結(jié)
這篇文章主要為大家介紹了十個(gè)Vue.js中有用的自定義鉤子,讓我們的代碼更加好看。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-04-04vue完成項(xiàng)目后,打包成靜態(tài)文件的方法
今天小編就為大家分享一篇vue完成項(xiàng)目后,打包成靜態(tài)文件的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09vue-cli 引入jQuery,Bootstrap,popper的方法
這篇文章主要介紹了vue-cli 引入jQuery,Bootstrap,popper的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-09-09使用iView Upload 組件實(shí)現(xiàn)手動(dòng)上傳圖片的示例代碼
這篇文章主要介紹了使用iView Upload 組件實(shí)現(xiàn)手動(dòng)上傳圖片的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10