欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于vue中根据用户权限动态添加路由的问题

程序员文章站 2022-06-25 10:46:07
根据用户的权限,展示不同的菜单页。知识点路由守卫(使用了前置守卫):根据用户角色判断要添加的路由vuex:保存动态添加的路由难点每次路由发生变化时都需要调用一次路由守卫,并且store中的数据会在每次...

根据用户的权限,展示不同的菜单页。

知识点

路由守卫(使用了前置守卫):根据用户角色判断要添加的路由
vuex:保存动态添加的路由

难点

每次路由发生变化时都需要调用一次路由守卫,并且store中的数据会在每次刷新的时候清空,因此需要判断store中是否有添加的动态路由。
(若没有判断 则会一直添加 导致内存溢出)

关于vue中根据用户权限动态添加路由的问题

根据角色判断路由
过滤动态路由 判断每条路由角色是否与登录传入的角色一致

关于vue中根据用户权限动态添加路由的问题

<template>
  <div>
    <el-menu
      :default-active="$route.path"
      class="el-menu-vertical-demo menu_wrap"
      background-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',
    component: () => import('../views/index.vue'),
    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', roles: ['customer'] }
      },
      {
        path: 'psw',
        name: 'psw',
        component: () => import('../views/one/password.vue'),
        meta: { title: 'psw', roles: ['customer'] }
      }
    ]
  },
  {
    path: '/card',
    name: 'navigationtwo',
    component: () => import('../views/index.vue'),
    meta: { title: '导航二'},
    children: [
      {
        path: 'activity',
        name: 'activity ',
        component: () => import('../views/three/activity.vue'),
        meta: { title: 'activity', roles: ['customer'] }
      },
      {
        path: 'social',
        name: 'social',
        component: () => import('../views/three/social.vue'),
        meta: { title: 'social', roles: ['customer'] }
      },
      {
        path: 'content',
        name: 'content',
        component: () => import('../views/three/content.vue'),
        meta: { title: 'content', roles: ['customer'] }
      }
    ]
  },
  {
    path: '/two',
    name: 'navigationthree',
    component: () => import('../views/index.vue'),
    meta: { title: '导航三'},
    children: [
      {
        path: 'index',
        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',
    component: () => import('../views/index.vue'),
    name: 'agent',
    meta: { title: 'agent', roles: ['agent','staff']},
    children: [
      {
        path: 'one',
        name: 'agentone',
        component: () => import('@/views/agent/one'),
        meta: { title: 'agentone', roles: ['agent','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', roles: ['agent','staff']  }
      }
    ]
  },
  // staff3
  {
    path: '/staff',
    component: () => import('../views/index.vue'),
    name: 'staff',
    meta: { title: 'staff', roles: ['staff']},
    children: [
      {
        path: 'one',
        name: 'staffone',
        component: () => import('@/views/staff/one'),
        meta: { title: 'staffone', roles: ['staff']  }
      },
      {
        path: 'two',
        name: 'stafftwo',
        component: () => import('@/views/staff/two'),
        meta: { title: 'stafftwo', roles: ['staff']  }
      },
      {
        path: 'three',
        name: 'staffthree',
        component: () => import('@/views/staff/three'),
        meta: { 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 { roles } = data
      return new promise(resolve =>{
        let addasyncrouters = filterasyncrouter(asyncrouter, roles)
        commit('getrouter', addasyncrouters)
        resolve()
      })
    }
  }
})

到此这篇关于vue中根据用户权限动态添加路由详解的文章就介绍到这了,更多相关vue动态添加路由内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!