在頁面A(源頁面)上點擊一個卡片,穿透到頁面B(目標頁面)。將來自卡片A的特定“查詢和統計參數”攜帶到頁面B。頁面B也可以通過其他方式訪問(例如,從菜單欄直接進入)。頁面B的初始狀態:當通過其他入口直接打開時,頁面B有自己的一套默認查詢參數。

 “兩種情況互相獨立,互不干擾”。

目標頁面(B)具有雙重身份:

它可以是一個獨立的頁面,帶有自己的一套默認參數(例如,通過菜單訪問時)。

它可以是來自頁面A的特定查詢的“結果視圖”,在這種情況下,它應該使用傳入的參數。

“互不干擾”。這意味著一個入口點的邏輯不應該破壞或影響另一個入口點的邏輯。頁面B的默認狀態應保持不變,除非穿透邏輯明確地改變它

使用 Router Query 的解決方案:

頁面A(發送方):如何導航?useRouter() 和 router.push()

頁面B(接收方):如何讀取URL參數?useRoute()

如何應用“兩種情況互相獨立”的邏輯?這是問題的核心。

需要:

  1. 一個用于頁面B默認狀態的來源。稱之為 defaultParams。
  2. 一個用于穿透參數的來源。那就是 route.query。
  3. 一個用來決定使用哪一套(或如何組合它們)的機制。
    •  使用一個 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>

為什么這個方案可以解決這個問題?

  1. 邏輯隔離:defaultParamsroute.query 在代碼中是兩個完全獨立的數據源,它們在各自的“軌道”上運行,沒有直接的合并或覆蓋操作,從根本上避免了“干擾”。

  2. 決策清晰:computed 屬性 finalParams 成為一個明確的“決策中心”。它的內部 if/else 邏輯清晰地表達了“非此即彼”的選擇,完美對應了“兩種情況互相獨立”。

  3. 狀態可預測:

    • 從菜單進入:URL干凈,hasQueryParameters 為 false,使用默認軌道。頁面狀態100%由 defaultParams 決定。
    • 從頁面A穿透:URL帶參,hasQueryParameters 為 true,使用穿透軌道。頁面狀態100%由 route.query 決定。
    • 用戶刷新頁面:URL保持不變,computed 會重新計算并得出與刷新前完全相同的決策,狀態保持一致。
  4. 易于維護與擴展:

    • 如果要修改頁面的默認行為,只需改 defaultParams,與穿透邏輯無關。
    • 如果頁面A需要傳遞一個新參數,只需在A的 query 中添加,頁面B會自動在穿透軌道中接收并使用。
    • 如果未來增加第三種情況(比如從頁面C穿透,邏輯不同),只需在 computed 中增加一個 else if 分支即可,結構清晰,不會影響現有邏輯。