關於vue中根據使用者許可權動態新增路由的問題
阿新 • • 發佈:2021-11-08
根據使用者的許可權,展示不同的選單頁。
知識點
路由守衛(使用了前置守衛):根據使用者角色判斷要新增的路由
x:儲存動態新增的路由
難點
每次路由發生變化時都需要呼叫一次路由守衛,並且store中的資料會在每次重新整理的時候清空,因此需要判斷store中是否有新增的動態路由。
(若沒有判斷 則會一直新增 導致記憶體溢位)
根據角色判斷路由
過濾動態路由 判斷每條路由角色是否與登入傳入的角色一致
<template> <div> <el-menu :default-active="$route.path" class="el-menu-vertical-demo menu_wrap" backgroundhttp://www.cppcns.com-color="#324057" text-color="white" active-text-color="#20a0ff" :collapse="isCollapse" unique-opened router > <el-submenu v-for="item in $store.state.Routers" :key="item.path" :index="item.path" v-if="!item.hidden" > <template slot="title" > <i class="el-icon-location"></i> <span>{{ item.meta.title }}</span> </template> <div v-for="chi in item.children" :key="chi.name"> <el-menu-item v-if="!chi.hidden" :index="item.path + '/' + chi.path"> <i class="el-icon-location"></i>{{ chi.meta.title }} </el-menu-item> </div> </el-submenu> </el-menu> </div> </template> <script> export default { name: "MenuList",data() { return { isCollapse: false,}; },created() { this.$bus.$on("getColl",(data) => { this.isCollapse = data; }); },methods: { } }; </script> <style scoped> .menu_wrap { height: 100vh; } .el-menu-vertical-demo:not(.el-menu--collapse) { width: 200px; height: 100vh; } </style>
import Vue from 'vue' import VueRouter from 'vue-router' import store from '../store/index' Vue.use(VueRouter) const originalPush = VueRouter.prototype.push VueRouter.prototype.push = function push(location) { return originalPush.call(this,location).catch(err => err) } export const routes = [ { path: '/home',name: 'First',component: () => import('../views/Index.vue'),meta: { title: 'Home'},children: [ { path: 'index',name: 'Home',component: () => import('../views/Home'),meta: { title: 'Home',roles: ['Customer'] } } ] },{ path: '/index',name: 'NavigationOne',meta: { title: '導航一'},children: [ { path: 'personnel',name: 'Personnel ',component: () => import('../views/One/Personnel.vue'),meta: { title: 'Personnel',roles: ['Customer'] } },{ path: 'account',name: 'Account',component: () => import('../views/One/Account.vue'),meta: { title: 'Account',{ path: 'psw',name: 'psw',component: () => import('../views/One/Password.vue'),meta: { title: 'psw',{ path: '/card',name: 'NavigationTwo',meta: { title: '導航二'},children: [ { path: 'activity',name: 'Activity ',component: () => import('../views/Three/Activity.vue'),meta: { title: 'Activity',{ path: 'Social',name: 'Social',component: () => import('../views/Three/Social.vue'),meta: { title: 'Social',{ path: 'content',name: 'Content',component: () => import('../views/Three/Content.vue'),meta: { title: 'Content',{ path: '/two',name: 'NavigationThree',meta: { title: '導航三'},name: 'Two ',component: () => import('../views/Two'),meta: { title: 'Two',roles: ['Customer'] } }] },{ path: '/404',name: 'Error',hidden: true,meta: { title: 'error'},component: () => import('../views/Error') } ] export const asyncRouter = [ // Agent3 Staff2 { path: '/agent',name: 'Agent',meta: { title: 'Agent',roles: ['Agent','Staff']},children: [ { path: 'one',name: 'agentOne',component: () => import('@/views/agent/One'),meta: { title: 'agentOne','Staff'] } },{ path: 'two',name: 'agentTwo',component: () => import('@/views/agent/Two'),meta: { title: 'agentTwo',roles: ['Agent'] } },{ path: 'three',name: 'agentThree',component: () => import('@/views/agent/Three'),meta: { title: 'agentThree','Staff'] } } ] },// Staff3 { path: '/staff',name: 'Staff',meta: { title: 'Staff',roles: ['Staff']},name: 'StaffOne',component: () => import('@/views/Staff/One'),meta: { title: 'StaffOne',roles: ['Staff'] } },name: 'StaffTwo',component: () => import('@/views/Staff/Two'),meta: { title: 'StaffTwo',name: 'StaffThree',component: () => import('@/views/Staff/Three'),meWpAUUsBta: { title: 'StaffThree',roles: ['Staff'] } } ] },{ path: '*',redirect: '/404',hidden: true } ] const router = new VueRouter({ routes }) router.beforeEach((to,from,next) =>{ let roles = ['Staff'] if(store.state.Routers.length) { console.log('yes') next() } else { console.log('not') store.dispatch('asyncGetRouter',{roles}) .then(res =>{ router.addRoutes(store.state.addRouters) }) next({...to}) // next()與next({ ...to })的區別:next() 放行 next('/XXX') 無限攔截 } }) export default router
import Vue from 'vue' import Vuex from 'vuex' import modules from './module' import router,{routes,asyncRouter} from '../router' function hasPermission(route,roles) { if(route.meta && route.meta.roles) { return roles.some(role =>route.meta.roles.indexOf(role) >= 0) } else { return true } } /* 遞迴過濾非同步路由表 返回符合使用者角色的路由 @param asyncRouter 非同步路由 @param roles 用戶角色 */ function filterAsyncRouter(asyncRouter,roles) { let filterRouter = asyncRouter.filter(route =>{ if(hasPermission(route,roles)) { if(route.children && route.children.length) { route.children = filterAsyncRouter(route.children,roles) } return true } return false }) return filterRouter } Vue.use(Vuex) export default new Vuex.Store({ state: { addRouters: [],Routers: [] },mutations: { getRouter(state,paload) { // console.log(paload) state.Routers = routes.concat(paload) state.addRouters = paload // router.addRoutes(paload) } },actions: { asyncGetRouter({ commit },data) { const http://www.cppcns.com{ roles } = data return new Promise(resolve =>{ let addAsyncRouters = filterAsyncRouter(asyncRouter,roles) commit('getRouter',addAsyncRouters) resolve() }) } } })
到此這篇關於vue中根據使用者許可權動態新增路由詳解的文章就介紹到這了,更多相關vue動態新增路由內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!