赞
踩
关键字
即匹配前端路由meta.menu值
来实现权限管理通常会把路由权限列表存至vux中
meta.menu来实现权限匹配
通过 router.addRoute来实现路由添加
通过meta.hidden 来决定是否在侧边栏展示当前页面
router/index.js
中完成 无需权限路由的配置
我这里配备的便是 登录 404
和首页
const routes = [{ path: '/login', component: () => import('@/views/Login.vue'), meta: { title: '登录' } }, { path: '/404', name: '404', component: () => import('@/views/error/404'), hidden: true }, { path: '', redirect: '/', component: Layout, children: [{ path: '/', component: () => import('../views/Home.vue'), meta: { title: '首页', parentpath: '/home' } }] } ]
存放在vueX中
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { rolelist: [], // 后端返回的路由数据 asyncRouters: [], // 所有需要分配权限的路由 finallyRouters: [], // 最终筛选出的路由 }, mutations: { setRoleList(state, data) { state.rolelist = data }, setAsyncRouter(state, asyncRouters) { state.asyncRouters = asyncRouters }, setFinallyRouters(state, data) { // 因为总体是用addRoute 添加 所以这儿用的concat 一个一个拼接 state.finallyRouters = state.finallyRouters.concat(data) // console.log(state.finallyRouters, '最后的路由') } }, actions: { async SetAsyncRouter({ commit }) { var list = [ // 景区 { path: '/scenic', redirect: '/scenic/index', component: (resolve) => require(['@/views/layout/index.vue'], resolve), meta: { menu: "spot", title: '景区', }, children: [{ path: 'index', name: "scenicManager", component: (resolve) => require(['@/views/scenic/index.vue'], resolve), meta: { title: '景区管理', menu: "scenic" } }, //景区 { path: 'detail', name: 'scenicDetail', hidden: true, component: (resolve) => require(['@/views/scenic/components/detail.vue'], resolve), meta: { title: '景区详情', menu: "scenic", } }, { path: 'manage/detail', name: "scenicManageDetail", hidden: true, component: (resolve) => require(['@/views/scenic/components/manageDetail.vue'], resolve), meta: { title: '管理详情', menu: "scenic" } }, ] }, // 用户 { path: '/User', redirect: '/User/index', component: () => import('@/views/layout/index.vue'), meta: { title: '会员', menu: "member" }, children: [ // 用户 { path: 'index', name: 'User', component: (resolve) => require(['@/views/member/user/index.vue'], resolve), meta: { title: '用户', menu: "user" } }, { path: 'detail', name: 'userDetail', hidden: 'true', component: (resolve) => require(['@/views/member/user/detail.vue'], resolve), meta: { title: '用户', menu: "detail" } }, { path: 'staff', name: 'UserStaff', component: (resolve) => require(['@/views/member/staff/index.vue'], resolve), meta: { title: '员工', menu: "manager" } }, { path: 'supplier', name: 'UserSupplier', component: (resolve) => require(['@/views/member/supplier/index.vue'], resolve), meta: { title: '供应商', menu: "thirdPlat" } }, ] }, commit('setAsyncRouter', list) }, }, modules: {}, getters: { asyncRouters(state) { return state.asyncRouters } } })
可在main.js 或者router/index.js
中写// 关键 添加flag防止多次获取动态路由和栈溢出 let asyncRouterFlag = 0; router.beforeEach(async (to, from, next) => { const token = window.localStorage.getItem('token') document.title = to.meta.title if (to.path == '/login') { next() } else { if (!token) { next('/login') } else { if (!asyncRouterFlag) { // 添加flag防止多次获取动态路由和栈溢出 asyncRouterFlag++ //同步调用获取菜单方法 await store.dispatch('SetAsyncRouter') //发请求获取菜单,并将菜单设置到vuex中, const asyncRouters = store.getters['asyncRouters']; var roleList = store.state.rolelist || [] if (roleList.length > 0) { // 自写方法 根据关键词匹配 addRouter(asyncRouters, roleList) } else { await api.LoginInfo().then(res => { console.log(res, '数据') if (res.code == 200) { roleList = res.data.roles store.commit('setRoleList', roleList) console.log(4) addRouter(asyncRouters, roleList) } else { Message.error(res.data.message || res.statusText); } }).catch(err => { next('/login') }) } next({ ...to, replace: true }) } else { next() } } } }) // 筛选出满足条件的路由 这里因人而异 function addRouter(asyncRouters, roleList) { asyncRouters.map(item => { if (roleList.indexOf(item.meta.menu) > -1) { let temp = cloneLoop(item) delete temp.children if (item.children.length > 0) { temp.children = [] item.children.map(item1 => { if (roleList.indexOf(item1.meta.menu) > -1) { temp.children.push(item1) // 最终路由存放至vuex中 store.commit('setFinallyRouters', temp) } }) } router.addRoute(temp) } }) // 最后 加入* 重定向404 router.addRoute({ path: '*', redirect: "/404", }) }
最后在实现侧边栏
<template> <div> <el-menu :default-active="this.$route.path" active-text-color='#13C479' class="el-menu-vertical-demo" router> <!-- 首页 --> <el-menu-item index="/"> // 图标 可自定义 <i class="el-icon-s-home"></i> <span slot="title" style="margin-left:10px">首页</span> </el-menu-item> <el-submenu :index="item.path" v-for="(item,index) in routeList" :key="index"> <template slot="title"> <i class="el-icon-s-home"></i> <span slot="title" style="margin-left:10px" v-if="item.meta">{{item.meta.title}}</span> </template> <template v-if="item.children"> <div v-for="(item1,index1) in item.children" :key="index1"> <el-menu-item :index="`${item.path}/${item1.path}`" v-if="!item1.hidden"> <i class="el-icon-s-home"></i> <span slot="title" style="margin-left:10px" >{{item1.meta.title}}</span> </el-menu-item> </div> </template> </el-submenu> </el-menu> </div> </template> <script> export default { data() { return { routeList: [] }; }, computed: {}, watch: {}, mounted() { // 这里把无需权限的路由复制过来 var tempRouter = [ // 订单 { path: "/order", component: () => import("@/views/layout/index.vue"), redirect: "/order/index", meta: { title: "订单" }, children: [ { path: "index", name: "orderTickets", component: () => import("@/views/order/tickets.vue"), meta: { title: "系统门票订单" } }, { path: "seasonTickets", name: "orderSeasonTickets", component: () => import("@/views/order/seasonTickets.vue"), meta: { title: "套餐门票订单" } } ] }, // 优惠券 { path: "/coupon", component: () => import("@/views/layout/index.vue"), redirect: "/coupon/index", meta: { title: "优惠券" }, children: [ { path: "index", name: "coupon", component: () => import("@/views/coupon/index.vue"), meta: { title: "优惠券" } } ] } ]; // 把筛选出来的权限列表和无需权限的列表组合起来 this.routeList = [...this.$store.state.finallyRouters, ...tempRouter]; console.log(this.routeList, "全部"); }, methods: {} }; </script> <style lang='scss' scoped> .el-menu-vertical-demo:not(.el-menu--collapse) { width: 200px; min-height: 400px; } /deep/ .el-menu { background: none; } </style>
login() { this.username = ""; this.password = ""; if (!this.loginForm.username) { this.username = "请输入账号"; } else if (!this.loginForm.password) { this.password = "请输入密码"; } else { this.loading = true; api .login(this.loginForm) .then(res => { // console.log(res, "登陆"); if (res.code === 200) { window.localStorage.setItem("token", res.data.token); this.$store.commit("setRoleList", res.data.roles); window.localStorage.setItem( "buttenpremissions", JSON.stringify(res.data.permissions) ); this.$router.push("/"); } }) .catch(err => { console.log(err); }); } }
后端没有返回refush-token
时,退出登录切换账号我们需要清除已经注册的路由,防止其他用户获得到已经注册好了的路由。router.replace({path: '/login'});
window.location.reload();
service.interceptors.response.use((res) => { console.log(res, '我是拦截') // if(res.) nprogress.done() return res.data }, err => { let status = err.response.status if (err.response && err.response.status) { console.log(err.response) if (status == 401) { Message.error('登录失效,请刷新后重试') router.replace({path: '/login'}); window.location.reload(); } } return Promise.reject(err.response)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。