目录

前言

一、动态路由是什么?

二、如何实现

1.登录时将获取的路由信息存入vuex

2.持久化处理

3.加载动态路由

总结


前言

最近在学习vue3时,准备用vite+vue3弄一个后台管理系统,于是准备看看动态路由的实现方式。


一、动态路由是什么?

动态路由,顾名思义是动态获取的,是可变的。我们可以根据不同的角色身份加载不同的路由,使用动态路由不仅更加灵活,还便于维护,我们可以将路由信息存入数据库,前端只需通过一个页面对路由进行增删改。

静态的路由:

二、如何实现

一般我们在登录的时候会都调用用户信息的接口,根据接口返回的菜单信息可以得到该用户的所有路由,前端再将获取到的路由用vuex存起来(此处要做持久化处理,不然刷新一遍路由菜单就不见了),然后我们在路由前置守卫处动态获取vuex中存储的路由,对页面进行渲染,即可完成。

1.登录时将获取的路由信息存入vuex

在登录页将获取到的路由信息存入vuex(此处为方便展示全是静态数据,后续可替换成调用接口获取):

constlogin = () => {
  if (loginForm.username === '' || loginForm.password === '') {
    ElMessage.error('账号或密码不能为空')
  } elseif (loginForm.username === 'admin' || loginForm.password === '123456') {
    localStorage.setItem("token", "abcdefg")
    userInfo.$patch({
      username: loginForm.username,
      password: loginForm.password
    })
    Menu.$patch({
      menuList: [
        {
          path: "/test",
          name: "test",
          url: "/testpage/index",
          icon: "house",
          title: '首页',
          children: [],
        },
        {
          path: "/next",
          name: "next",
          url: "/nextpage/index",
          icon: "user",
          title: '其他',
          children: [],
        },
        {
          path: "/other",
          name: "other",
          icon: "setting",
          title: '设置',
          children: [
            {
              path: "/page",
              name: "page",
              url: "/nextchildpage/index",
              icon: "location",
              title: '子页面1',
              children: [],
            },
            {
              path: "/page2",
              name: "page2",
              url: "/childpage/index",
              icon: "location",
              title: '子页面2',
              children: [],
            }
          ]
        }
      ]
    })
    router.push("/")
  }
  else {
    localStorage.setItem("token", "abcdefg")
    userInfo.$patch({
      username: loginForm.username,
      password: loginForm.password
    })
    Menu.$patch({
      menuList: [
        {
          path: "/test",
          name: "test",
          url: "/testpage/index",
          icon: "house",
          title: '首页',
          children: [],
        },
        {
          path: "/next",
          name: "next",
          url: "/nextpage/index",
          icon: "user",
          title: '其他',
          children: [],
        },
        {
          path: "/other",
          name: "other",
          icon: "setting",
          title: '设置',
          children: [
            {
              path: "/page",
              name: "page",
              url: "/nextchildpage/index",
              icon: "location",
              title: '子页面1',
              children: [],
            }
          ]
        }
      ]
    })
    router.push("/")
  }

}

2.持久化处理

在登录完成后我们需要将路由信息进行存入缓存,不然刷新之后vuex中的菜单信息便会清空。

const useMenuList = defineStore('menulist', {
  state: () => ({
    menuList: [
      {
        path: "/test",
        name: "test",
        url: "/testpage/index",
        icon: "house",
        title: '首页',
        children: [],
      },
      {
        path: "/next",
        name: "next",
        url: "/nextpage/index",
        icon: "user",
        title: '其他',
        children: [],
      },
      {
        path: "/other",
        name: "other",
        icon: "setting",
        title: '设置',
        children: [
          {
            path: "/page",
            name: "page",
            url: "/nextchildpage/index",
            icon: "location",
            title: '子页面1',
            children: [],
          },
          {
            path: "/page2",
            name: "page2",
            url: "/childpage/index",
            icon: "location",
            title: '子页面2',
            children: [],
          }
        ]
      }
    ]
  }),
  persist: {
    enabled: true, // 这个配置代表存储生效,而且是整个store都存储strategies: [
      { storage: localStorage, paths: ['menuList'] }, // accessToken字段用 localstorage存储
    ],
  }
})
exportdefault useMenuList

可以看到数据已经存入缓存中了,刷新也不会清空。

3.加载动态路由

在main.js中动态加载路由,这里只做了二级菜单,后续可优化成多级。

// 加载动态路由
let modules = import.meta.glob('./views/**/*.vue')
useMenuList().$state.menuList.forEach(navigation => {
  Router.addRoute('home', {
    path: navigation.path,
    meta: { title: navigation.title, isAuth: navigation.isAuth, icon: navigation.icon },
    name: navigation.name,
    component: modules[`./views${navigation.url}.vue`]
  })
  if (navigation.children) {
    navigation.children.forEach(childeNav => {
      Router.addRoute(navigation.name, {
        path: childeNav.path,
        meta: { title: childeNav.title, isAuth: childeNav.isAuth, icon: childeNav.icon },
        name: childeNav.name,
        component: modules[`./views${childeNav.url}.vue`]
      })
    })
  }
})

总结

以上就是前端动态路由的全部内容,本文仅仅简单介绍了实现的思路,代码写的比较随意,而动态路由则可使前端菜单配置、权限配置更加灵活且更好维护。

Logo

前往低代码交流专区

更多推荐