一、背景

现在很多公司的vue项目都是一套模板加平台配置系统。角色权限、菜单名称、菜单图标都可以在平台配置系统上傻瓜式配置。笔者这篇文章主要讲解其中的动态路由,如果你是一位前端工程师,我想你会渴望知道其中的代码是如何实现的,如果你是后端工程师,希望我下面的代码不是那么晦涩难懂。另外我很欣赏你爱学习的精神。话不多说下面就是干货了~

二、代码实现

为了更方便的学习,笔者模拟了后端的接口数据,你可以复制粘贴直接使用~

export const dynamicRouters = [
  {
    path: '/home', //注意不要重复,唯一!!
    name: 'home', //注意不要重复,唯一!!
    mate: {
      title: '首页',    //这个是菜单项名字
      icon: 'el-icon-s-home', //图标class 可以先不管
    },
    component: "/home/home", 这个是组件路径,正常来说是'@component/home/home'
   }
]

好了拿到数据之后,我们需要在用户登陆成功后动态加入,这里为了方便,不管他是什么角色有什么权限,我都返回上面的路由,如果在业务场景中,你可以让后台根据不同角色返回不同的路由,从而实现权限控制。下面再src下新建一个permission.js文件放入如下代码

import router from './router'        //默认路由文件,可以放不用权限配置的页面
import store from './store/store'    // vuex 一般路由数据都存在这里面,为了全局的数据绑定。
import { dynamicRouters } from "./components/mock.js"  //这里就是后台返回的数据你懂的~

router.beforeEach((to, from, next) => {
  if (sessionStorage.getItem('token')) {    //判断用户是否已经登陆
    if (to.path === '/' && sessionStorage.getItem('token')) {
      next({ path: '/home' })
    } else {
      if (store.getters.menuRouter.length === 0) {    //这里判断下vuex中是否有了动态路由数据
        store.dispatch('SET_MENU_ROUTER', dynamicRouters).then(() => { //这里对后台数据做处理
          router.addRoutes(store.getters.menuRouter)    //关键看这里 取出后台数据,把数据从这加入
          next({ path: to.path === '/home' ? '/home' : to.path })
        })
      } else {
        next();
      }
    }
  } else {
    next();
  }
})

注意还没完,上面我们执行store.dispath('SET_MENU_ROUTER',dynamicRouters)方法对数据进行了处理,你也需要,代码如下

//这里是vuex的内容,我默认你是会的~~
const importRouter = (url) => {
  return () => import('@/components' + url)    //这里把真实路径补正确
}

function filterAsyncRouter(asyncRouterMap) {    //递归处理路由懒加载
  const accessedRouters = asyncRouterMap.filter(route => {
    route.component = importRouter(route.component)
    if (route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children)
    }
    return true
  })

  return accessedRouters
}
const state = {
  menuRouter: [],        // 存储路由
}
const getters = {
  menuRouter: (state) => {
    return state.menuRouter    //返回给addRouter使用
  },
}
const mutations = {
  setMenuRouter(state, menuRouter) {
    state.menuRouter = menuRouter    // 设置存储
  },
}
const actions = {
  SET_MENU_ROUTER({ commit }, menuRouter) {
    return new Promise(resolve => {
      const accessedRouters = filterAsyncRouter(menuRouter) //调用
      // console.log(accessedRouters);
      commit('setMenuRouter', accessedRouters)    //调用mutations中的方法,你懂的~
      resolve()    //回调实现
    })
  },
}

搞定!

Logo

前往低代码交流专区

更多推荐