在頁面A(源頁面)上點擊一個卡片,穿透到頁面B(目標頁面)。將來自卡片A的特定“查詢和統計參數”攜帶到頁面B。頁面B也可以通過其他方式訪問(例如,從菜單欄直接進入)。頁面B的初始狀態:當通過其他入口直接打開時,頁面B有自己的一套默認查詢參數。
“兩種情況互相獨立,互不干擾”。
目標頁面(B)具有雙重身份:
它可以是一個獨立的頁面,帶有自己的一套默認參數(例如,通過菜單訪問時)。
它可以是來自頁面A的特定查詢的“結果視圖”,在這種情況下,它應該使用傳入的參數。
“互不干擾”。這意味著一個入口點的邏輯不應該破壞或影響另一個入口點的邏輯。頁面B的默認狀態應保持不變,除非穿透邏輯明確地改變它
使用 Router Query 的解決方案:
頁面A(發送方):如何導航?useRouter() 和 router.push()
頁面B(接收方):如何讀取URL參數?useRoute()
如何應用“兩種情況互相獨立”的邏輯?這是問題的核心。
需要:
- 一個用于頁面B默認狀態的來源。稱之為
defaultParams。 - 一個用于穿透參數的來源。那就是
route.query。 - 一個用來決定使用哪一套(或如何組合它們)的機制。
- 使用一個
computed屬性提供“決策邏輯”。- 創建一個
computed屬性finalParams,它封裝了if/else決策邏輯。
- 創建一個
- 使用一個
watch + onMounted 來觸發實際的數據獲?。?code>fetchData),使用計算出的 finalParams。
詳細代碼實現
步驟一:頁面A (發送方) - 發起穿透
1 <!-- PageA.vue --> 2 <template> 3 <button @click="goToPageB">穿透到頁面B,并攜帶參數</button> 4 </template> 5 6 <script setup> 7 import { useRouter } from 'vue-router'; 8 9 const router = useRouter(); 10 11 const goToPageB = () => { 12 router.push({ 13 name: 'PageB', // 假設路由名為 'PageB' 14 // query對象就是開啟“穿透軌道”的鑰匙 15 query: { 16 projectId: 'P-12345', 17 status: 'critical', 18 source: 'card-click' // 可以加一個來源標識,便于調試 19 } 20 }); 21 }; 22 </script>
步驟二:頁面B (接收方) - 雙軌決策
這是實現“互不干擾”的核心。我們將使用 computed 屬性來創建一個清晰的決策器
<!-- PageB.vue --> <script setup> import { computed, watchEffect } from 'vue'; import { useRoute } from 'vue-router'; const route = useRoute(); // ================================================================= // 軌道一:【默認軌道】的定義 // 這是頁面B的“出廠設置”,完全獨立,不受任何外部影響。 // ================================================================= const defaultParams = Object.freeze({ status: 'all', dateRange: 'lastMonth', sortBy: 'createdAt', projectId: '', }); // ================================================================= // 核心:【雙軌決策器】 // 它的職責是判斷當前應該使用哪條軌道的參數。 // 這個邏輯本身就是“兩種情況互相獨立”的最佳體現。 // ================================================================= const finalParams = computed(() => { // 判斷信號:URL中是否存在任何查詢參數? // 這是區分兩種情況的唯一標準。 const hasQueryParameters = Object.keys(route.query).length > 0; if (hasQueryParameters) { // 【走上穿透軌道】 // URL中有參數,說明是穿透場景。 // 完全、僅使用外部傳來的參數,忽略默認設置。 // console.log('[PageB] 檢測到穿透參數,使用【穿透軌道】'); return { ...route.query }; } else { // 【走上默認軌道】 // URL中沒有參數,說明是獨立訪問場景。 // 完全、僅使用頁面內部的默認參數。 // console.log('[PageB] 未檢測到穿透參數,使用【默認軌道】'); return { ...defaultParams }; } }); // ================================================================= // 數據獲取層 // 它只關心最終確定的參數,而不關心參數來自哪條軌道。 // ================================================================= const fetchData = () => { // 在這里,finalParams.value 是一個清晰、確定的參數集 console.log('--- [PageB] 準備加載數據 ---'); console.log('最終決策的參數集:', finalParams.value); // 調用API,使用 finalParams.value // yourApiService.fetchList(finalParams.value); }; // watchEffect會自動追蹤 computed 屬性 finalParams // 當 finalParams 發生變化時(無論是首次加載還是URL變化),它都會重新執行 fetchData watchEffect(() => { fetchData(); }); </script>
為什么這個方案可以解決這個問題?
-
邏輯隔離:
defaultParams和route.query在代碼中是兩個完全獨立的數據源,它們在各自的“軌道”上運行,沒有直接的合并或覆蓋操作,從根本上避免了“干擾”。 -
決策清晰:
computed屬性finalParams成為一個明確的“決策中心”。它的內部if/else邏輯清晰地表達了“非此即彼”的選擇,完美對應了“兩種情況互相獨立”。 -
狀態可預測:
- 從菜單進入:URL干凈,
hasQueryParameters為false,使用默認軌道。頁面狀態100%由defaultParams決定。 - 從頁面A穿透:URL帶參,
hasQueryParameters為true,使用穿透軌道。頁面狀態100%由route.query決定。 - 用戶刷新頁面:URL保持不變,
computed會重新計算并得出與刷新前完全相同的決策,狀態保持一致。
- 從菜單進入:URL干凈,
-
易于維護與擴展:
- 如果要修改頁面的默認行為,只需改
defaultParams,與穿透邏輯無關。 - 如果頁面A需要傳遞一個新參數,只需在A的
query中添加,頁面B會自動在穿透軌道中接收并使用。 - 如果未來增加第三種情況(比如從頁面C穿透,邏輯不同),只需在
computed中增加一個else if分支即可,結構清晰,不會影響現有邏輯。
- 如果要修改頁面的默認行為,只需改
浙公網安備 33010602011771號