to:进入到哪个路由去
from:从哪个路由离开
next:路由的控制参数,常用的有next(true)和next(false)
首先判断进入的是否是login页面?然后再判断是否已经登陆?
已经登陆了就进入你要跳转的页面,没登录就进入login页面为了更加明显一点,我将页面命名的简单一些,ps:
Login.vue是登陆页面
Index.vue是全局页面(包含公共导航组件)
A.vue是普通页面(此处我做为首页)
B.vue是普通页面
permission.js router.beforeEach(async(to, from, next) => { NProgress.start() document.title = getPageTitle(to.meta.title) const hasToken = getToken() // 判断是否存在token,没有就重新登陆 if (hasToken) { if (to.path === '/login') { // if is logged in, redirect to the home page next({ path: '/' }) NProgress.done() } else { // 这里指的是src/store/getters.js的roles const hasRoles = store.getters.roles && store.getters.roles.length > 0 if (hasRoles) { next() } else { try { // 获取roles // get user info 获取当前登录用户的Button按钮列表,和当前用户角色名 store.dispatch('user/getInfo') // generate accessible routes map based on roles 获取后端角色列表 const DbRoutes = await store.dispatch('permission/getSideMenus') router.addRoutes(DbRoutes) 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() } } } } })
const getters = { token: state => state.user.token, name: state => state.user.name, roles: state => state.user.roles,//角色名列表 permission_routes: state => state.permission.routes,//页面路由 permissions: state => state.user.permissions //菜单按钮列表 } export default getters
import { login, logout, getInfo, getRoleList } from '@/api/user' import { getToken, setToken, removeToken } from '@/utils/auth' import router, { resetRouter } from '@/router' const state = { token: getToken(), roles: [] } const mutations = { SET_TOKEN: (state, token) => { state.token = token }, //存储登录角色信息 SET_ROLES: (state, roles) => { state.roles = roles }, //存储按钮信息 SET_PERMISSIONS: (state, permissions) => { state.permissions = permissions } } const actions = { // get user info getInfo({ commit, state }) { return new Promise((resolve, reject) => { getInfo(state.token).then(response => { const { data } = response if (!data) { reject('Verification failed, please Login again.') } const { roles, permissions } = data console.error('roles' + roles) console.error('permissions' + permissions) // roles must be a non-empty array if (!roles || roles.length <= 0) { reject('getInfo: roles must be a non-null array!') } if (!permissions || permissions.length <= 0) { reject('getInfo: permissions must be a non-null array!') } commit('SET_ROLES', roles) commit('SET_PERMISSIONS', permissions) resolve(data) }).catch(error => { reject(error) }) }) } } export default { namespaced: true, state, mutations, actions }
const actions = { getSideMenus({ commit, state }) { return new Promise((resolve, reject) => { //import { listForRouter } from '@/api/user' listForRouter().then(response => { const menus = response.data //import { traverseRoutes } from '@/utils/router' const remoteroutes = traverseRoutes(menus) commit('SET_ROUTES', remoteroutes) resolve(remoteroutes) }).catch(error => { console.log('list', error) router.replace({ path: '/login', query: { redirect: router.currentRoute.path } }) // reject(error) }) }) } }
import { traverseRoutes } from '@/utils/router'
export function traverseRoutes(menus) { const routes = menus.map(menu => { if (menu.children === null) { menu.children = [] } if (menu.component) { const name = menu.component menu.component = (resolve) => require(['@/' + name], resolve) // menu.component = resolve => require(['@/views/UserManagement/user'], resolve) } if (menu.children && menu.children.length) { menu.children = traverseRoutes(menu.children) } return menu }) return routes }
api文件夹下user.js import { userInfo} from '@/api/user' export function getInfo(token) { return request({ url: '/admin/info', method: 'get', params: { token } }) }
export function listForRouter() { return request({ url: '/admin/getLoginSideBarMenus', method: 'get' }) }
{ "code":200, "msg":"成功", "data": {"permissions":["userAdd","userDeleted","userUpdated","userReset","userSetRole","roleAdd","userDeleted", "roleUpdated","authAdd","authDeleted","authUpdated"], "roles":["超级管理员"] } }
后端admin/getLoginSideBarMenus返回给前端信息
{"code":200,"msg":"成功", "data":[{"id":1,"parentId":0,"path":"/system","component":"layout","name":"系统管理","num":1,"hidden":false,"url":"/system","meta":{"title":"系统管理","icon":"form"},"children":[{"id":2,"parentId":1,"path":"/user","component":"views/UserManagement/user.vue","name":"用户管理","num":1,"hidden":false,"url":"/user","meta":{"title":"用户管理","icon":"user"},"children":null},{"id":8,"parentId":1,"path":"/role","component":"views/UserManagement/role.vue","name":"角色管理","num":1,"hidden":false,"url":"/role","meta":{"title":"角色管理","icon":"international"},"children":null},{"id":14,"parentId":1,"path":"/auth","component":"views/UserManagement/auth.vue","name":"资源管理","num":1,"hidden":false,"url":"/auth","meta":{"title":"资源管理","icon":"list"},"children":null},{"id":18,"parentId":1,"path":"/test","component":"views/test/index.vue","name":"测试菜单","num":1,"hidden":false,"url":"/test","meta":{"title":"测试菜单","icon":"lock"},"children":[{"id":19,"parentId":18,"path":"/children1","component":"views/test/children/children1.vue","name":"测试菜单1","num":2,"hidden":false,"url":"/children1","meta":{"title":"测试菜单1","icon":"icon"},"children":null}]}]}]}
// main.js import { checkArray } from './utils/btnPermission.js' Vue.directive('permission', { inserted(el, binding) { const permission = binding.value // 获取到 v-permission的值 if (permission) { const hasPermission = checkArray(permission) // 检测是否有权限 if (!hasPermission) { // 没有权限 移除Dom元素 el.parentNode && el.parentNode.removeChild(el) } } } })
import store from '@/store' export function checkArray(key) { // store.dispatch('user/getInfo') const arr = store.getters.permissions //store文件下getter. const index = arr.indexOf(key) if (index > -1) { return true // 有权限 } else { return false // 无权限 } }
界面使用方法 auth.js
界面使用方法 auth.js <el-table-column fixed="right" label="操作" width="300px"> <template slot-scope="scope"> <el-button v-permission="'authAdd'" icon="el-icon-plus" type="success" size="small" @click="add(scope.row.code,scope.row.pcodes)" > 新增子级 </el-button> <el-button v-permission="'authUpdated'" type="primary" icon="el-icon-edit" size="small" @click="handleEdit(scope.row.id, scope.row)" >编辑</el-button> <el-button v-permission="'authDeleted'" type="danger" icon="el-icon-delete" size="small" @click.native.prevent="deleted(scope.row.id)" > 删除 </el-button> </template> </el-table-column>