vue-admin-template极简的 vue admin 管理后台的动态路由实现方法

项目源码地址:GitHub - PanJiaChen/vue-admin-template: a vue2.0 minimal admin template

注意:项目中的路由均写在 src\router\index.js 中,其中默认包含 constantRoutes 数组,这是固定路由,无论用户是什么角色,都需要显示这些路由内容(即导航栏)。

export const constantRoutes = [
    ...
]

为了根据权限来动态的生成路由,我们需要添加 asyncRoutes 数组,这里面的内容将根据用户角色权限动态生成路由内容(即导航栏)。

export const asyncRoutes = [
    ...
]

实现方法:

① 在 src\store\modules\permission.js 中,通过分析 asyncRoutes 里面的角色权限和当前用户所拥有的角色权限,生成用户可查看到的路由列表 permission_routes

② 在 src\layout\components\Sidebar\index.vue 中,遍历 permission_routes 显示菜单栏。

配置步骤

1、在 src\router\index.js 文件中

固定路由的写法,不需要任何权限,所有角色都可以访问

/**
 * 固定路由
 * 没有权限要求的基页
 * 所有角色都可以访问
 */
export const constantRoutes = [
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },
  {
    path: '/404',
    component: () => import('@/views/404'),
    hidden: true
  },
  {
    path: '/dashboard',
    component: () => import('@/views/dashboard/index'),
    hidden: true
  }
  /* {
    path: '/',
    component: Layout,
    redirect: '/dashboard',
    children: [{
      path: 'dashboard',
      name: 'Dashboard',
      component: () => import('@/views/dashboard/index'),
      meta: { title: '首页' }
    }]
  } */
]

动态路由的写法,需要我们添加的地方,根据权限显示的路由

/**
 * 异步路由
 * 需要根据用户角色动态加载的路由
 */
export const asyncRoutes = [
  // 用户端 start
  {
    path: '/rescueActivity',
    redirect: '/rescueActivity',
    component: Layout,
    meta: { roles: ['user'] },
    children: [
      {
        path: '/rescueActivity',
        name: 'rescueActivity',
        component: () => import('@/views/user/rescue-activity'),
        meta: { title: '志愿救助活动' }
      }
    ]
  },
  // 用户端 end
  // 管理员端 start
  {
    path: '/userManage',
    redirect: '/userManage',
    component: Layout,
    meta: { roles: ['admin'] },
    children: [
      {
        path: '/userManage',
        name: 'userManage',
        component: () => import('@/views/admin/user-manage'),
        meta: { title: '用户管理' }
      }
    ]
  },
  // 管理员端 end
  // 404页一定要放在最后!!!
  { path: '*', redirect: '/404', hidden: true }
]

通过修改 meta 属性中 roles

只有 admin 角色可以查看:meta: { roles: ['admin'] }

admin 和 user 都可以查看:meta: { roles: ['admin', 'user'] }

注意:{ path: '*', redirect: '/404', hidden: true } 必须放在最后面,并且只能放在 asyncRoutes 中,如果放在 constantRoutes 中的话,刷新页面会报 404 错误

2、在 src\store\modules\user.js 文件中

① 在 getDefaultState 里面的 avatar: '', 后面添加 roles: [] 值,如图:

roles: []

② 在 mutations 里面的 SET_AVATAR: (state, avatar) => { state.avatar = avatar }, 后面添加 SET_ROLES: (state, roles) => { state.roles = roles } 值,如图:

SET_ROLES: (state, roles) => {
  state.roles = roles
}

③ 在 getInfo 方法里面的 commit('SET_AVATAR', avatar) 后面添加 commit('SET_ROLES', roles) 值,如图:

const { name, avatar, roles } = data
commit('SET_ROLES', roles)

④ 在 logout、resetToken 方法里面的 commit('RESET_STATE') 后面添加 commit('SET_ROLES', []) 值,如图:

commit('SET_ROLES', [])

3、添加 src\store\modules\permission.js 文件

在 src\store\modules 目录下面没有 permission.js 文件,需要添加

permission.js
import { asyncRoutes, constantRoutes } from '@/router'

/**
 * 使用 meta.role 来确定当前用户是否具有权限
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * 通过递归过滤异步路由表
 * @param routes 异步路由
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []
  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })
  return res
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    // 这个地方维护了两个状态一个是addRouters,一个是routes
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

4、在 src\store\getters.js 文件中

在 getters 里面的 name: state => state.user.name, 后面添加 roles: state => state.user.roles,  permission_routes: state => state.permission.routes 值,如图:

roles: state => state.user.roles,
permission_routes: state => state.permission.routes

5、将 src\permission.js 文件里面的内容全部替换掉

import router, { constantRoutes } from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'

NProgress.configure({ showSpinner: false }) // NProgress Configuration

const whiteList = ['/login'] // no redirect whitelist

router.beforeEach(async(to, from, next) => {
  // start progress bar
  NProgress.start()

  // set page title
  document.title = getPageTitle(to.meta.title)

  // determine whether the user has logged in
  const hasToken = getToken()

  if (hasToken) {
    if (to.path === '/login') {
      // if is logged in, redirect to the home page
      next({ path: '/' })
      NProgress.done()
    } else {
      const hasRoles = store.getters.roles && store.getters.roles.length > 0
      if (hasRoles) {
        next()
      } else {
        try {
          // get user info
          // note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
          const { roles } = await store.dispatch('user/getInfo')
          // generate accessible routes map based on roles
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
          // dynamically add accessible routes
          router.options.routes = constantRoutes.concat(accessRoutes)
          router.addRoutes(accessRoutes)

          // hack method to ensure that addRoutes is complete
          // set the replace: true, so the navigation will not leave a history record
          next({ ...to, replace: true })
        } catch (error) {
          // remove token and go to login page to re-login
          await store.dispatch('user/resetToken')
          Message.error(error || 'Has Error')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    /* has no token*/

    if (whiteList.indexOf(to.path) !== -1) {
      // in the free login whitelist, go directly
      next()
    } else {
      // other pages that do not have permission to access are redirected to the login page.
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  // finish progress bar
  NProgress.done()
})

6、在 src\layout\components\Sidebar\index.vue 文件中

将原来的 <sidebar-item ... /> 替换掉

<sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" />

在 ...mapGetters 里面的 'sidebar', 后面添加 'permission_routes' 值,如图:

'permission_routes'

7、在 src\store\index.js 文件中

import user from './modules/user' 下面添加 import permission from './modules/permission' 导入 permission 值;在 new Vuex.Store 里面的 user, 后面添加 permission 值,如图:

import permission from './modules/permission'
permission

  • 29
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我们来一步步搭建一个基于vue-admin-template后台管理系统。 ## 1. 准备工作 首先需要安装好node.js和npm,并确保版本符合要求。然后我们需要安装vue-cli脚手架工具,通过以下命令安装: ``` npm install -g vue-cli ``` 安装完成后,我们就可以使用vue-cli来创建一个基于vue-admin-template的项目了。 ## 2. 创建项目 使用以下命令创建一个vue-admin-template项目: ``` vue init vuejs-templates/admin vue-admin-demo ``` 其中,vue-admin-demo为项目名称,根据自己的需要修改即可。 创建完成后,进入项目目录并安装依赖: ``` cd vue-admin-demo npm install ``` 安装完成后,我们可以启动项目并查看效果: ``` npm run dev ``` 打开浏览器,访问http://localhost:9528,就可以看到一个基于vue-admin-template后台管理系统了。 ## 3. 配置路由 在src/router/index.js文件中,我们可以看到已经定义了一个路由: ```javascript import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld } ] }) ``` 我们可以根据自己的需要修改这个路由,添加更多的路由信息。比如,我们可以添加一个Dashboard页面的路由: ```javascript import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' import Dashboard from '@/views/dashboard/index' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld }, { path: '/dashboard', name: 'Dashboard', component: Dashboard } ] }) ``` ## 4. 配置菜单 在src/layout/components/Sidebar/index.vue文件中,我们可以看到已经定义了一个菜单: ```javascript <el-submenu index="1"> <template slot="title"> <i class="el-icon-location"></i> <span>Dashboard</span> </template> <el-menu-item index="1-1">Dashboard 1</el-menu-item> <el-menu-item index="1-2">Dashboard 2</el-menu-item> <el-menu-item index="1-3">Dashboard 3</el-menu-item> </el-submenu> ``` 我们可以根据自己的需要修改这个菜单,添加更多的菜单项。比如,我们可以添加一个Dashboard页面的菜单项: ```javascript <el-submenu index="1"> <template slot="title"> <i class="el-icon-location"></i> <span>Dashboard</span> </template> <el-menu-item index="/dashboard">Dashboard</el-menu-item> </el-submenu> ``` ## 5. 配置页面 我们可以在src/views目录下添加自己的页面,比如Dashboard页面。创建一个dashboard目录,并在其中添加一个index.vue文件。 在index.vue文件中,我们可以像普通的vue组件一样编写代码,比如: ```vue <template> <div> <h1>Dashboard</h1> </div> </template> <script> export default { name: 'Dashboard' } </script> ``` ## 6. 打包部署 当我们完成了开发工作后,就可以将项目打包部署到生产环境中了。使用以下命令进行打包: ``` npm run build ``` 打包完成后,会在项目根目录下生成一个dist目录,里面包含了打包后的文件。 我们可以将dist目录中的文件上传到服务器,并配置好Web服务器,以便访问我们的后台管理系统。 至此,我们就完成了基于vue-admin-template后台管理系统的搭建。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值