uni-app頁面、組件視圖數據無法刷新問題的解決辦法

問題

先總結一下無法刷新頁面或組件視圖數據的可能原因:

  1. 數據本身的問題
  2. 沒有爲模塊或組件創建 key
  3. 路由使用不當

以我個人的經歷,目前歸結爲此三點,本文主要探討後兩個問題的解決辦法,當然可能還有其他問題, 歡迎各位同行與我交流。

場景

最近做一個教育類APP的二次開發,使用的是Uni-app,做的差不多的時候出現一個問題:登錄後,用戶中心主頁頁面的視圖數據無論怎樣都無法刷新,然後試了各種方法,最後發現問題的關鍵之前的開發對登錄後的跳轉做了錯誤的處理,即使用了 uni.navigateTo,而驗證登錄狀態後,在沒有登錄的情況下跳轉到登錄頁同樣也是使用了 uni.navigateTo

其實 uni.navigateTo 在登錄後的內頁使用是非常合適的,因爲它會緩存頁面和數據,所以能很好的提高APP性能和用戶體驗。

但如果在登錄之初就使用 uni.navigateTo ,這就很致命,因爲登錄成功之前一般還無法獲取APP的內頁數據的,如果使用了 uni.navigateTo ,就會導致登錄成功後, 即便已經刷新了數據,併成功加入了緩存,你會發現通過 uni.navigateTo 加載的主頁的視圖數據還是不會刷新,因爲 uni.navigateTo 把頁面緩存了,這種用法實在太坑了。

有人可能會說,我在頁面、組件生命週期裏面更新數據不就完了嗎?其實大部分方法是不可行的,因爲頁面緩存後再返回,在不刷新頁面的情況下,生命週期中的方法不會被調用,當然 setTimeout() 或者 setInterval() 除外(但這這種辦法會損失性能,如果處理不當用戶體驗會很糟)

解決辦法

1. 數據本身的問題

如網絡問題,或者處理的方式和時機(生命週期)不當,這個需要自查,不在本文討論範圍內。

2. 沒有爲模塊或組件創建 key

目前 uni-app 還無法使用類似 Vue 中的 watch 方法來監聽數據變化以更新視圖,也無法監聽 data 中數組或對象的變化。

所以碰到需要動態更新數據,刷新頁面或組件視圖時,需要使用 key 屬性來刷新,代碼示例如下:

數據處理完成後,通過修改 key 的值變可以刷新該模塊或組件,前提是爲該模塊或組件設置了 key 屬性

<template>
	<view>
		<view class="module-box1" :key="moduleKey"></view>
		<commponent1 v-if="PageCur=='commponent1'" :key="commponent1Key"></commponent1>
		<commponent2 v-if="PageCur=='commponent2'" :key="commponent2Key"></commponent2>
		
		<view class="module-box2">
			<button	@tap="tapMenu" :data-cur="commponent1">按鈕1</button>
			<button	@tap="tapMenu" :data-cur="commponent2">按鈕1</button>
		</view>
	</view>
</template>

<script>
export default {
	data() {
		return {
			PageCur: 'commponent1',
			moduleKey: 0,
			commponent1Key: 0,
			commponent2Key: 0,
			
			},
		};
	},
	onLoad() {
		//獲取數據
		this.getData()

	},
	methods: {
		getData() {
			var that = this
			//獲取數據
			uni.request({
			    url: 'https://www.example.com/request',
			    success: (res) => {
			        console.log(res.data);
			        //相關處理
					//最後更新相應模塊或組件的key
					++that.moduleKey
					++that.commponent1Key
					++that.commponent2Key
			    }
			});
			
		},
		tapMenu(e) {
			var that = this
			this.PageCur = e.currentTarget.dataset.cur
		},
}
</script>

3. 路由使用不當

比如我現在碰到的問題,在登錄的地方錯誤使用了 uni.navigateTo(OBJECT),解決辦法就是改爲 uni.redirectTo(OBJECT)或者 uni.reLaunch(OBJECT) ,這兩個方法都會關閉當前頁面再跳轉,區別是後者會把所有頁面都關閉。

在登錄處理中建議使用 uni.reLaunch(OBJECT)

uni.reLaunch({
	url: '../dirName/moduleName'
});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章