routes.ts 2.13 KB
import type { RouteRecordRaw } from 'vue-router'
import Layout from '@/layout/index.vue'
import { HOME_PATH } from '@/config'

/**
 * 动态路由的父级容器:所有后端菜单生成的页面都挂在这个 Layout 下
 *
 * 这里**静态注册**(而不是等菜单加载完再 addRoute)有两个好处:
 *  1. `/` 任何时候都能匹配,不会出现 vue-router 的 "No match found for location with path /" 告警
 *  2. 即使某账号一个菜单都没有,也仍有可用的外壳页面,不会白屏
 * 业务子路由由 permission store 用 `router.addRoute('Root', child)` 动态追加。
 */
export const layoutRoute: RouteRecordRaw = {
  path: '/',
  name: 'Root',
  component: Layout,
  redirect: HOME_PATH,
  children: []
}

/**
 * 静态路由:不依赖后端菜单,登录页 / 外壳 / 404 / 重定向 / 兜底
 * 业务路由全部由后端 get-permission-info 下发的菜单动态生成(见 store/modules/permission.ts)
 */
export const staticRoutes: RouteRecordRaw[] = [
  layoutRoute,
  {
    path: '/login',
    name: 'Login',
    component: () => import('@/views/login/index.vue'),
    meta: { title: '登录', hidden: true }
  },
  {
    path: '/404',
    name: 'NotFound',
    component: () => import('@/views/error/404.vue'),
    meta: { title: '页面不存在', hidden: true }
  },
  {
    path: '/redirect',
    component: Layout,
    meta: { hidden: true },
    children: [
      {
        path: '/redirect/:path(.*)',
        name: 'Redirect',
        component: () => import('@/views/redirect/index.vue'),
        meta: { hidden: true }
      }
    ]
  }
]

/**
 * 兜底:必须最后注册
 *
 * 必须带 name:permission store 的 resetRoutes() 靠 `hasRoute(notFoundRoute.name)`
 * 找回并移除它。没有 name 时那里只能拿 'notFound' 这个假名字去查,永远查不到,
 * 于是每次切换账号/重新生成路由都会再注册一条 catch-all(不断累积)。
 * 路由名本身也用来判断「这个地址当前账号够不够得着」。
 */
export const notFoundRoute: RouteRecordRaw = {
  path: '/:pathMatch(.*)*',
  name: 'NotFoundCatchAll',
  redirect: '/404',
  meta: { hidden: true }
}