在main.js同级创建permission.js
import router from './router/index'
import store from './store'
import NProgress from 'nprogress' // progress bar
const whiteList = ['/login']
router.beforeEach(async(to, from, next) => {
NProgress.start()
const hasToken = store.getters.token
if (hasToken) {
if (to.path === '/login') {
next({ path: '/' })
NProgress.done()
} else {
// testMenu 请求数据 可访问的路由列表
const testMenu = [
{
menus: 'goodsManager',
name: '商品管理'
},
{
menus: 'vipManager',
name: '会员管理'
},
]
if (testMenu.length > 0) {
store.dispatch('GenerateRoutes', { testMenu }).then(() => {
router.addRoutes(store.getters.addRouters)
})
next()
} else {
next()
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
next()
// NProgress.done()
}
}
})
router.afterEach(() => {
NProgress.done()
})
在store/modules下创建permission.js
import { asyncRouterMap, constantRouterMap } from '@/router/index'
// 判断是否有权限访问该菜单
function hasPermission(menus, route) {
if (route.name) {
const currMenu = getMenu(route.name, menus)
if (currMenu != null) {
// 设置菜单的标题、图标和可见性
if (currMenu.title != null && currMenu.title !== '') {
route.meta.title = currMenu.title
}
return true
} else {
route.sort = 0
if (route.hidden !== undefined && route.hidden === true) {
return true
} else {
return false
}
}
} else {
return true
}
}
// 根据路由名称获取菜单
function getMenu(name, menus) {
for (let i = 0; i < menus.length; i++) {
const menu = menus[i]
if (name === menu.menus) {
return menu
}
}
return null
}
const permission = {
state: {
routers: constantRouterMap,
addRouters: []
},
mutations: {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers
const currentRouter = JSON.parse(JSON.stringify(constantRouterMap))
currentRouter.forEach(item => {
if (item.name === 'home') {
item.children = item.children.concat(routers)
}
})
// state.routers = constantRouterMap.concat(routers)
state.routers = currentRouter
}
},
actions: {
GenerateRoutes({ commit }, data) {
return new Promise(resolve => {
const accessedRouters = asyncRouterMap.filter(v => {
if (hasPermission(data.testMenu, v)) {
if (v.children && v.children.length > 0) {
return v
} else {
return v
}
}
return false
})
commit('SET_ROUTERS', accessedRouters)
resolve()
})
}
}
}
export default permission
router/index.js
// 商品
import goodsRouter from './modules/goods'
// 登录
import Login from '@/views/login/Login'
// 注册
import Register from '@/views/register/Register'
// Home
import Home from '@/views/home/Home'
export const constantRouterMap = [
{
path: '/login',
name: 'login',
component: Login
},
{
path: '/register',
name: 'register',
component: Register
},
{
path: '/',
redirect: '/index',
name: 'home',
component: Home,
children: [{
path: 'index',
name: 'index',
component: Index,
meta: { title: '首页', iconImg: indexIcon }
}]
}
]
export const asyncRouterMap = [
// 商品router
goodsRouter,
// 会员router
vipRouter,
]
export default new Router({
routes: constantRouterMap
})
router 下goods模块写法
// 如果子路由都在Home的children下 必须引入Home
// 商品管理——首页
import GoodsManager from '@/views/goods-manager/Index'
// Home
import Home from '@/views/home/Home'
const goodsRouter = {
path: '/goodsManager',
name: 'goodsManager',
redirect: '/goodsManager/addGoods',
// 这必须是Home 不然写在Home的头部会不在
component: Home,
children: [{
path: 'addGoods',
name: 'addGoods',
component: AddGoods
}],
}
// 有种情况上面这种情况会把原本的样式打乱在最外面嵌套一次路由
{
path: 'goodsIndex',
name:'goodsIndex,
// 这必须是Home 不然写在Home的头部会不在
component:Home,
redirect: '/goodsIndex/goodsManager',
children: [{
path: '/goodsManager',
name: 'goodsManager',
redirect: '/goodsIndex/goodsManager/addGoods',
component: goodsManager,
children: [{
path: 'addGoods',
name: 'addGoods',
component: AddGoods
}]
}]
}
}
export default goodsRouter
在Home里面用
import { mapGetters } from 'vuex'
computed: {
...mapGetters(['routers']),
routerMenuList() {
var menuList = []
if (this.routers.length > 0) {
// this.routers.forEach(item => {
// if (item.name !== 'login' && item.name !== 'login') {
// menuList.push(item)
// }
// })
menuList = this.routers[2].children
}
return menuList
}
}
<el-menu
:default-active="activePath"
:router="true"
class="el-menu-demo hl-menu"
mode="horizontal"
@select="handleSelectMenu"
>
<el-menu-item
v-for="(item, index) in routerMenuList"
:key="index"
class="menu-item"
:index="item.redirect? item.redirect :item.name"
>
<i
class="item-icon"
>
<img :src="item.meta.iconImg">
</i>
<i
class="item-title"
>
{{ item.meta?item.meta.title:'' }}</i>
<i
:class="
activePath.split('/')[1] === item.name?'item-bottom-icon':''
"
/>
</el-menu-item>
</el-menu>