Skip to content

路由同導覽

路由由特性套件管理,而非各應用。應用外殼將每個特性嘅 routes 導出組合成一個路由實例。

1. 路由實例

@vh5/app-shell 統一創建路由,適配應用無需配置路由。

ts
const featureRoutes = mergeRouteModules([...homeRoutes, ...productRoutes, ...userRoutes]);

export const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    { path: "/", component: BasicLayout, redirect: "/home", children: featureRoutes },
    ...authRoutes,
    { path: "/:pathMatch(.*)*", component: () => import("../views/NotFound.vue") },
  ],
});

2. 特性路由模組

ts
export const productRoutes: RouteRecordRaw[] = [
  {
    path: "product",
    name: "product-list",
    component: () => import("./views/List.vue"),
    meta: { title: "商品列表", authority: ["user", "admin"], tab: true },
  },
];

meta 字段說明:

字段類型說明
titlestring文件標題 + 導航欄標題
authoritystring[]允許訪問嘅角色(省略 ⇒ 已登錄即可訪問)
publicboolean唔需要登錄即可訪問
tabboolean喺底部 TabBar 顯示入口
keepAliveboolean<KeepAlive> 包裹視圖

3. 權限守衛

ts
router.beforeEach((to) => {
  startProgress();
  if (to.meta.public) return true;
  const auth = useAuthStore();
  if (!auth.isAuthenticated) return { name: "login", query: { redirect: to.fullPath } };
  const required = to.meta.authority as string[] | undefined;
  if (required && !required.some(auth.hasRole)) return { name: "forbidden" };
  return true;
});
router.afterEach(() => stopProgress());

4. 動態標題

ts
watchEffect(() => {
  const title = router.currentRoute.value.meta?.title as string | undefined;
  useTitle(title ? `${title} - Vue H5 Template` : "Vue H5 Template");
});
ts
watchEffect(() => {
  const routeTitle = router.currentRoute.value.meta?.title;
  useTitle(routeTitle ? `${routeTitle} - Vue H5 Template` : "Vue H5 Template");
});

Released under the MIT License.