Skip to content

路由和菜单

项目提供了基础的路由系统,可以根据路由文件动态生成菜单结构以及动态注册路由。

路由类型

路由分为两种类型,静态路由和动态路由,静态路由是项目启动就确定好的路由;动态路由是用户登录后通过菜单数据动态生成的路由。

静态路由

静态路由用于不需要权限就能访问的路由,如:登录、注册、404、500 等

静态路由配置在 src/router/index.ts 目录下

ts
const staticRoutes: AppRouteRecordRaw[] = [];

动态路由

动态路由用于需要权限才能访问的路由,如:用户管理、菜单管理等

动态路由配置在 src/router/modules/asyncRoutes.ts 目录下

ts
const asyncRoutes: MenuListType[] = [];

路由定义

静态路由跟动态路由定义方式的方式基本上一致,请看下面的示例:

静态路由

ts
const staticRoutes: AppRouteRecordRaw[] = [
  {
    path: RoutesAlias.Login,
    name: "Login",
    component: () => import("@views/login/index.vue"),
    meta: { title: "menus.login.title", isHideTab: true, setTheme: true },
  },
  {
    path: RoutesAlias.Register,
    name: "Register",
    component: () => import("@views/register/index.vue"),
    meta: {
      title: "menus.register.title",
      isHideTab: true,
      noLogin: true,
      setTheme: true,
    },
  },
  {
    path: RoutesAlias.ForgetPassword,
    name: "ForgetPassword",
    component: () => import("@views/forget-password/index.vue"),
    meta: {
      title: "menus.forgetPassword.title",
      isHideTab: true,
      noLogin: true,
      setTheme: true,
    },
  },
];

动态路由

ts
const asyncRoutes: MenuListType[] = [
  {
    id: 3,
    name: "User",
    path: "/user",
    component: RoutesAlias.Home,
    meta: {
      title: "menus.user.title",
      icon: "",
      keepAlive: false,
    },
    children: [
      {
        id: 301,
        path: "account",
        name: "Account",
        component: RoutesAlias.Account,
        meta: {
          title: "menus.user.account",
          keepAlive: true,
        },
      },
      {
        id: 302,
        path: "department",
        name: "Department",
        component: RoutesAlias.Department,
        meta: {
          title: "menus.user.department",
          keepAlive: false,
        },
      },
    ],
  },
];

嵌套路由

ts
{
  id: 3,
  path: '/menu',
  name: 'Menu',
  component: RoutesAlias.Home,
  meta: {
    title: 'menus.menu.title',
    icon: '',
    keepAlive: false
  },
  children: [
    {
      id: 402,
      path: 'nested',
      name: 'Nested',
      component: '',
      meta: {
        title: 'menus.menu.nested',
        icon: '',
        keepAlive: true
      },
      children: [
        {
          id: 40201,
          path: 'menu1',
          name: 'NestedMenu1',
          component: RoutesAlias.NestedMenu1,
          meta: {
            title: 'menus.menu.menu1',
            icon: '',
            keepAlive: true
          }
        },
        {
          id: 40202,
          path: 'menu2',
          name: 'NestedMenu2',
          component: '',
          meta: {
            title: 'menus.menu.menu2',
            icon: '',
            keepAlive: true
          },
          children: [
            {
              id: 4020201,
              path: 'menu2-1',
              name: 'NestedMenu2-1',
              component: RoutesAlias.NestedMenu21,
              meta: {
                title: 'menus.menu.menu21',
                icon: '',
                keepAlive: true
              }
            }
          ]
        },
        {
          id: 40203,
          path: 'menu3',
          name: 'NestedMenu3',
          component: '',
          meta: {
            title: 'menus.menu.menu3',
            icon: '',
            keepAlive: true
          },
          children: [
            {
              id: 4020301,
              path: 'menu3-1',
              name: 'NestedMenu3-1',
              component: RoutesAlias.NestedMenu31,
              meta: {
                title: 'menus.menu.menu31',
                icon: '',
                keepAlive: true
              }
            },
            {
              id: 4020302,
              path: 'menu3-2',
              name: 'NestedMenu3-2',
              component: '',
              meta: {
                title: 'menus.menu.menu32',
                icon: '',
                keepAlive: true
              },
              children: [
                {
                  id: 402030201,
                  path: 'menu3-2-1',
                  name: 'NestedMenu3-2-1',
                  component: RoutesAlias.NestedMenu321,
                  meta: {
                    title: 'menus.menu.menu321',
                    icon: '',
                    keepAlive: true
                  }
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

添加路由

你只需要在 /src/views/ 目录下创建一个页面,如:/src/views/safeguard/Server.vue

然后在对应的路由文件中添加一个路由对象,如下:

ts
{
  path: '/safeguard',
  name: 'Safeguard',
  component: RoutesAlias.Home,
  meta: {
    title: '运维管理'
  },
  children: [
    {
      path: 'server',
      name: 'SafeguardServer',
      component: RoutesAlias.Server,
      meta: {
        title: '服务器管理'
      }
    }
  ]
}

验证

到这里路由添加完成,访问 http://localhost:3006/safeguard/server, 如果能够正常访问,则表示路由和菜单定义成功。

路由和菜单类型

ts
export type MenuListType = {
  id: number;
  path: string; // 路由
  name: string; // 组件名
  component?: string; // 改为字符串类型,表示组件路径
  meta: {
    title: string; // 菜单名称
    icon?: string; // 菜单图标
    showBadge?: boolean; // 是否显示徽标
    showTextBadge?: string; // 是否显示新徽标
    isHide?: boolean; // 是否在菜单中隐藏
    isHideTab?: boolean; // 是否在标签页中隐藏
    link?: string; // 链接
    isIframe?: boolean; // 是否是 iframe
    keepAlive: boolean; // 是否缓存
    authList?: Array; // 可操作权限
    isInMainContainer?: boolean; // 是否在主容器中
  };
  children?: MenuListType[]; // 子菜单
};

meta

meta 是菜单的元数据,用于定义菜单的显示和行为。包含以下属性:

title

  • 类型:string
  • 默认值:''
  • 说明:菜单名称:可以是名称,多语言可以设置 i18n 的 key

icon

  • 类型:string
  • 默认值:''
  • 说明:菜单图标

showBadge

  • 类型:boolean
  • 默认值:false
  • 说明:是否显示徽标

showTextBadge

  • 类型:string
  • 默认值:''
  • 说明:是否显示文字徽标,可定义文字

isHide

  • 类型:boolean
  • 默认值:false
  • 说明:是否在菜单中隐藏

isHideTab

  • 类型:boolean
  • 默认值:false
  • 说明:是否在标签页中隐藏
  • 类型:string
  • 默认值:''
  • 说明:链接,内嵌页面链接、外部链接

isIframe

  • 类型:boolean
  • 默认值:false
  • 说明:是否是内嵌页面

keepAlive

  • 类型:boolean
  • 默认值:false
  • 说明:是否缓存

authList

  • 类型:Array
  • 默认值:[]
  • 说明:可操作权限

Released under the MIT License.