Sfoglia il codice sorgente

perf: 优化标签页操作-路由传参模式用法

xiaoxian521 1 anno fa
parent
commit
87da9b881c

+ 35 - 20
src/views/tabs/hooks.ts

@@ -1,54 +1,69 @@
+import { isString, isEmpty } from "@pureadmin/utils";
 import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
-import { useRouter, useRoute } from "vue-router";
-import { onBeforeMount } from "vue";
+import {
+  useRouter,
+  useRoute,
+  type LocationQueryRaw,
+  type RouteParamsRaw
+} from "vue-router";
 
 export function useDetail() {
   const route = useRoute();
   const router = useRouter();
-  const id = route.query?.id ? route.query?.id : route.params?.id;
+  const getParameter = isEmpty(route.params) ? route.query : route.params;
 
   function toDetail(
-    index: number | string | string[] | number[],
-    model: string
+    parameter: LocationQueryRaw | RouteParamsRaw,
+    model: "query" | "params"
   ) {
+    // ⚠️ 这里要特别注意下,因为vue-router在解析路由参数的时候会自动转化成字符串类型,比如在使用useRoute().route.query或useRoute().route.params时,得到的参数都是字符串类型
+    // 所以在传参的时候,如果参数是数字类型,就需要在此处 toString() 一下,保证传参跟路由参数类型一致都是字符串,这是必不可少的环节!!!
+    Object.keys(parameter).forEach(param => {
+      if (!isString(parameter[param])) {
+        parameter[param] = parameter[param].toString();
+      }
+    });
     if (model === "query") {
       // 保存信息到标签页
       useMultiTagsStoreHook().handleTags("push", {
         path: `/tabs/query-detail`,
         name: "TabQueryDetail",
-        query: { id: String(index) },
+        query: parameter,
         meta: {
           title: {
-            zh: `No.${index} - 详情信息`,
-            en: `No.${index} - DetailInfo`
+            zh: `No.${parameter.id} - 详情信息`,
+            en: `No.${parameter.id} - DetailInfo`
           },
+          // 如果使用的是非国际化精简版title可以像下面这么写
+          // title: `No.${index} - 详情信息`,
           // 最大打开标签数
           dynamicLevel: 3
         }
       });
       // 路由跳转
-      router.push({ name: "TabQueryDetail", query: { id: String(index) } });
-    } else {
+      router.push({ name: "TabQueryDetail", query: parameter });
+    } else if (model === "params") {
       useMultiTagsStoreHook().handleTags("push", {
         path: `/tabs/params-detail/:id`,
         name: "TabParamsDetail",
-        params: { id: String(index) },
+        params: parameter,
         meta: {
           title: {
-            zh: `No.${index} - 详情信息`,
-            en: `No.${index} - DetailInfo`
+            zh: `No.${parameter.id} - 详情信息`,
+            en: `No.${parameter.id} - DetailInfo`
           }
+          // 如果使用的是非国际化精简版title可以像下面这么写
+          // title: `No.${index} - 详情信息`,
         }
       });
-      router.push({ name: "TabParamsDetail", params: { id: String(index) } });
+      router.push({ name: "TabParamsDetail", params: parameter });
     }
   }
 
-  function initToDetail(model) {
-    onBeforeMount(() => {
-      if (id) toDetail(id, model);
-    });
-  }
+  // 用于页面刷新,重新获取浏览器地址栏参数并保存到标签页
+  const initToDetail = (model: "query" | "params") => {
+    if (getParameter) toDetail(getParameter, model);
+  };
 
-  return { toDetail, initToDetail, id, router };
+  return { toDetail, initToDetail, getParameter, router };
 }

+ 9 - 2
src/views/tabs/index.vue

@@ -56,10 +56,17 @@ function onCloseTags() {
         class="m-2"
         v-for="index in 6"
         :key="index"
-        @click="toDetail(index, 'query')"
+        @click="toDetail({ id: index }, 'query')"
       >
         打开{{ index }}详情页
       </el-button>
+      <el-button
+        @click="
+          toDetail({ id: 666, name: '小明', age: 18, job: '工程师' }, 'query')
+        "
+      >
+        多个参数
+      </el-button>
     </div>
 
     <el-divider />
@@ -70,7 +77,7 @@ function onCloseTags() {
         class="m-2"
         v-for="index in 6"
         :key="index"
-        @click="toDetail(index, 'params')"
+        @click="toDetail({ id: index }, 'params')"
       >
         打开{{ index }}详情页
       </el-button>

+ 5 - 2
src/views/tabs/params-detail.vue

@@ -5,10 +5,13 @@ defineOptions({
   name: "TabParamsDetail"
 });
 
-const { initToDetail, id } = useDetail();
+const { initToDetail, getParameter } = useDetail();
 initToDetail("params");
 </script>
 
 <template>
-  <div>{{ id }} - 详情页内容在此(params传参)</div>
+  <div>
+    {{ getParameter.id }} - 详情页内容在此(params传参)
+    <p>当前页面参数为:{{ getParameter }}</p>
+  </div>
 </template>

+ 5 - 2
src/views/tabs/query-detail.vue

@@ -5,10 +5,13 @@ defineOptions({
   name: "TabQueryDetail"
 });
 
-const { initToDetail, id } = useDetail();
+const { initToDetail, getParameter } = useDetail();
 initToDetail("query");
 </script>
 
 <template>
-  <div>{{ id }} - 详情页内容在此(query传参)</div>
+  <div>
+    {{ getParameter.id }} - 详情页内容在此(query传参)
+    <p>当前页面参数为:{{ getParameter }}</p>
+  </div>
 </template>