千家信息网

如何编写vue-router基于后端permissions动态生成导航菜单的代码

发表于:2024-11-23 作者:千家信息网编辑
千家信息网最后更新 2024年11月23日,本篇内容主要讲解"如何编写vue-router基于后端permissions动态生成导航菜单的代码",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何编写v
千家信息网最后更新 2024年11月23日如何编写vue-router基于后端permissions动态生成导航菜单的代码

本篇内容主要讲解"如何编写vue-router基于后端permissions动态生成导航菜单的代码",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"如何编写vue-router基于后端permissions动态生成导航菜单的代码"吧!

目录
  • Vue.js

  • 1、注册全局守卫

  • 2、Vuex状态管理 全局缓存routes

  • 3、路由拦截

  • 4、路由菜单

  • 5、递归菜单vue组件

Vue.js

  • vue-router

  • vuex

1、注册全局守卫

核心逻辑
1、token身份验证(后端) => token失效返回登录页面
2、获取用户权限
3、校验permissions,动态添加路由菜单

router.beforeResolve 注册一个全局守卫。和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。

router.beforeResolve(async (to, from, next) => {  let hasToken = store.getters['User/accessToken']  if (!settings.loginInterception) hasToken = true  if (hasToken) {    if (to.path === '/auth/sign-in') {      next({ path: '/' })    } else {      const hasPermissions =        store.getters['User/permissions'] &&        store.getters['User/permissions'].length > 0      if (hasPermissions) {        next()      } else {        try {          let permissions          if (!constant.loginInterception) {            // settings.js loginInterception为false时,创建虚拟权限            await store.dispatch('User/setPermissions', ['admin'])            permissions = ['admin']          } else {            permissions = await store.dispatch('User/getUserInfo')          }          let accessRoutes = []          accessRoutes = await store.dispatch('Routes/setRoutes', permissions)          // 添加路由          router.addRoutes(accessRoutes)          next({ ...to, replace: true })        } catch {          await store.dispatch('User/resetAccessToken')        }      }    }  } else {    if (settings.routesWhiteList.indexOf(to.path) !== -1) {      next()    } else {      next('/auth/sign-in')    }  }  document.title = getPageTitle(to.meta.title)})

settings.js 全局设置

export default {  // 是否开启登录拦截  loginInterception: true,  // 不经过token校验的路由  routesWhiteList: ['/auth/sign-in', '/auth/register', '/401', '/404'],}

2、Vuex状态管理 全局缓存routes

  • state :对数据的全局存储

  • getter: 可以理解为computed ,对数据进行计算

  • mutations :对数据的同步更改

  • actions:对数据的异步更改(实现异步操作)

  • module: 将 store 分割成模块

/** * @author Alan * @description 路由拦截状态管理 */import { asyncRoutes, constantRoutes } from '@/router'import { filterAsyncRoutes } from '@/Utils/handleRoutes'const state = () => ({  routes: [],  partialRoutes: []})const getters = {  routes: (state) => state.routes,  partialRoutes: (state) => state.partialRoutes}const mutations = {  setRoutes (state, routes) {    state.routes = constantRoutes.concat(routes)  },  setPartialRoutes (state, routes) {    state.partialRoutes = constantRoutes.concat(routes)  }}const actions = {  async setRoutes ({ commit }, permissions) {    const finallyAsyncRoutes = await filterAsyncRoutes(      [...asyncRoutes],      permissions    )    commit('setRoutes', finallyAsyncRoutes)    return finallyAsyncRoutes  },  setPartialRoutes ({ commit }, accessRoutes) {    commit('setPartialRoutes', accessRoutes)    return accessRoutes  }}export default { namespaced: true, state, getters, mutations, actions }

3、路由拦截

/** * @author Alan * @description 判断当前路由是否包含权限 * @param permissions * @param route * @returns {boolean|*} */export function hasPermission (permissions, route) {  if (route.meta && route.meta.permissions) {    return permissions.some((role) => route.meta.permissions.includes(role))  } else {    return true  }}/** * @author Alan * @description 根据permissions数组拦截路由 * @param routes * @param permissions * @returns {[]} */export function filterAsyncRoutes (routes, permissions) {  const finallyRoutes = []  routes.forEach((route) => {    const item = { ...route }    if (hasPermission(permissions, item)) {      if (item.children) {        item.children = filterAsyncRoutes(item.children, permissions)      }      finallyRoutes.push(item)    }  })  return finallyRoutes}

4、路由菜单

/** @author Alan* @description 公共路由*/export const constantRoutes = [  {    path: '/auth',    name: 'auth2',    component: AuthLayout,    children: authChildRoutes('auth2'),    hidden: true // 隐藏菜单  },  {    path: '/',    name: 'dashboard',    component: VerticleLayout,    meta: {      title: 'Dashboard',      name: 'sidebar.dashboard',      is_heading: false,      is_active: false,      link: '',      class_name: '',      is_icon_class: true,      icon: 'ri-home-4-line',      permissions: ['admin']    },    children: childRoutes('dashboard')  }]/** @author Alan* @description 异步路由*/export const asyncRoutes = [  {    path: '/menu-design',    name: 'horizontal-dashboard',    component: HorizantalLayout,    meta: {      title: 'Menu Design',      name: 'sidebar.MenuDesign',      is_heading: false,      is_active: false,      link: '',      class_name: '',      is_icon_class: true,      icon: 'ri-menu-3-line',      permissions: ['admin']    },    children: horizontalRoute('dashboard')  }, {    path: '/core',    name: 'core',    component: VerticleLayout,    meta: {      title: 'UI Elements',      name: 'sidebar.uiElements',      is_heading: false,      is_active: false,      class_name: '',      link: '',      is_icon_class: true,      icon: 'ri-pencil-ruler-line',      permissions: ['admin']    },    children: coreChildRoute('core')  }]

5、递归菜单vue组件

到此,相信大家对"如何编写vue-router基于后端permissions动态生成导航菜单的代码"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0