Skip to content

路由系统

路由过度效果

如果默认的路由动画不好看,你可以在src/layouts/components/common/RouterViewContent.vue里修改。

注意

虽然 vue3 已经支持了多个根组件,但是在启用了路由过度动画后,不能使用多个根组件,否则页面切换的时候白屏,即使是文本、注释也不可以, 也就是说template的第一个子元素必须是有效的 html 元素、组件。

正确示例:

vue
<template>
  <div></div>
</template>

错误示例:

存在多个根标签:

vue
<template>
  <div></div>
  <div></div>
</template>

注释也不行:

vue
<template>
  <div></div>
  <!-- 我是注释 -->
</template>

自动生成路由

rengar-admin的路由是基于src/views目录自动生成路由文件,无需手动配置, 自动生成的路由文件在src/router/routes.ts中,自动生成的路由的name类型文件位于typings/common/vite-plugin-routes.d.ts中。

提示

在生成的路由文件中,手动修改 meta 的配置、redirect配置不会被自动覆盖,其他的均会被自动覆盖。

生成规则

  1. 路由的path根据文件夹来命名。
  2. 叶子节点必须存在index.vue或者[xxx].vue的文件,否则会被忽略,不会生成路由。
  3. 路由的name为祖先的目录命名,以-连接。
  4. 路由的metatitle为祖先的目录命名,以_连接。
  5. [xxx].vue的文件,会被认为是动态路由,生成路由时,会自动生成params参数,如[id].vue会生成/:id

注意

src/views404homelogin文件目录不能删除,其他的目录可以删除。

单层路由

假设src/views目录下有如下目录结构:

bash
src
└── views
    ├── dashboard
   └── index.vue

则会自动生成如下路由:

ts
[
  {
    path: "/dashboard",
    name: "dashboard",
    meta: {
      title: 'dashboard'
    }
    component: () => import("@/views/dashboard/index.vue"),
  }
];

多级路由

假设src/views目录下有如下目录结构:

bash
src
└── views
    ├── dashboard
   ├── index.vue
   └── analysis
       └── index.vue
    ├── user
   └── list
       └── index.vue
   └── add
       └── [index].vue
   └── edit
       └── [id].vue   # 动态路由

则会自动生成如下路由:

ts
[
  {
    path: "/dashboard",
    name: "dashboard",
    meta: {
      title: 'dashboard'
    }
    component: () => import("@/views/dashboard/index.vue"),
    children: [
      {
        path: "/dashboard/analysis",
        name: "dashboard-analysis",
        meta: {
          title: 'dashboard_analysis'
        }
        component: () => import("@/views/dashboard/analysis/index.vue"),
      }
    ]
  },
  {
    path: "/user",
    name: "user",
    meta: {
      title: 'user'
    }
    children: [
      {
        path: "list",
        name: "user-list",
        meta: {
          title: 'user_list'
        }
        component: () => import("@/views/user/list/index.vue"),
      },
      {
        path: "add",
        name: "user-add",
        meta: {
          title: 'user_add'
        }
        component: () => import("@/views/user/add/index.vue"),
      },
      {
        path: "edit/:id",  # 动态路由
        name: "user-edit",
        meta: {
          title: 'user_edit'
        },
        component: () => import("@/views/user/edit/[id].vue"),
      }
    ]
  }
]

meta 配置

属性类型默认值说明
titlestring自动生成路由的标题,会被用于生成面包屑和菜单的名称
layut"base"或"blank"base页面的布局,默认为 base
rolesstring[]-权限设置
iconstring-菜单的图标,直接使用"iconify"的图标名
localIconstring-菜单的本地图标
keepAliveboolean-页面是否缓存
hideInMenuboolean-是否在菜单中隐藏
hideInTabboolean-是否在 tab 栏中隐藏
activeMenustring-当此页面被激活时,高亮显示的菜单的 name
constantboolean-是否是常量路由,设置了该选项后,不需要登录、不需要鉴权就能访问
ordernumber-排序
hrefstring-设置了会外部跳转该链接
fixedInTabboolean-是否固定在 tab 栏中

keep-alive

得益于vue-router的新特性,实现多级keep-alive非常简单, 要想实现页面kee-alive缓存,需要做如下配置:

  1. 路由的meta中设置keepAlive: true
  2. 当前路由的祖先路由中不允许出现component字段。

如:

ts
{
    path: "/user",
    name: "user",
    meta: {
      title: 'user'
    }, # 这里没有component字段
    children: [
      {
        path: "list",
        name: "user-list",
        meta: {
          title: 'user_list',
          keepAlive: true
        }
        component: () => import("@/views/user/list/index.vue"),
      },
    ]
  }

原理: rengar-admin会在构建的时候自动注入defineOptions({name: 'xxx'})xxx为当前路由的name。也就是说,在开发中手动设置路由组件的name是无效的。该自动注入插件位于packages/vite-plugin-vue-inject-name中。

路由跳转

为了路由跳转能获得类型提示,rengar-admin封装了自定义 hooks,位于src/hooks/router.ts中。

一个基本的路由示例

常见的列表、新增、编辑的示例。

目录结构:

bash
src
└── views
    ├── user
   └── list
       └── index.vue
   └── add
       └── index.vue
   └── edit
       └── [id].vue

路由:

ts
[
  {
    path: "/user",
    name: "user",
    meta: {
      title: '用户管理'
    },
    redirect: '/user/list',
    children: [
      {
        path: "list",
        name: "user-list",
        meta: {
          title: '用户列表',
          hideInMenu: true,
          activeMenu: 'user'
        }
        component: () => import("@/views/user/list/index.vue"),
      },
      {
        path: "add",
        name: "user-add",
        meta: {
          title: '新增用户',
          hideInMenu: true,
          activeMenu: 'user'
        }
        component: () => import("@/views/user/add/index.vue"),
      },
      {
        path: "edit/:id",  # 动态路由
        name: "user-edit",
        meta: {
          title: '编辑用户',
          hideInMenu: true,
          activeMenu: 'user'
        },
        component: () => import("@/views/user/edit/[id].vue"),
      }
    ]
  }
]

全局路由守卫流程图

全局路由守卫代码位于src/router/guard.ts中。

全局路由守卫流程图

去除自动生成路由

如果不需要自动生成路由,在build/plugins/index.ts移除路由插件:

ts
export function setupVitePlugins() {
  const plugins: PluginOption[] = [
    setupInject(),
    vue(),
    vueJsx(),
    vueDevTools(),
    setupRouter(), 
    setupUnocssPlugin(),
    ...setupAutoImportPlugin(),
    setupVersion(),
  ];
  return plugins;
}

就可以去src/router/routes.ts中手动配置路由了。