vue admin 动态路由权限管理

主要思路 通过后端接口返回数据 进行判断 (通过后端实现的权限管理有许多种),在这里 我们主要通过 关键字匹配前端路由meta.menu值来实现权限管理通常会把路由权限列表存至vux中

vue admin 动态路由权限管理_第1张图片

箭头所指的便是 后端接口返回的权限列表

实现方法通过 通过 配置路由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中

const asyncRouters=[
 {
     
          path: '/User',
          redirect: '/User/index',
          component: () => import('@/views/layout/index.vue'),
          meta: {
     
            title: '用户',
            menu: "user"
          },
          children: [
            // 用户
            {
     
              path: 'index',
              name: 'User',
              component: (resolve) => require(['@/views/member/user/index.vue'], resolve),
              meta: {
     
                title: '用户',
                menu: "user"
              }
            },
            {
     
              path: 'detail',
              name: 'userDetail',
              component: (resolve) => require(['@/views/member/user/detail.vue'], resolve),
              meta: {
     
                title: '用户',
                menu: "user"
              }
            },
            {
     
              path: 'staff',
              name: 'UserStaff',
              component: (resolve) => require(['@/views/member/staff/index.vue'], resolve),
              meta: {
     
                title: '员工',
                menu: "manager"
              }
            },
            // 这个路由不需要展示
            {
     
              path: 'supplier',
              name: 'UserSupplier',
              hidden:true,
              component: (resolve) => require(['@/views/member/supplier/index.vue'], resolve),
              meta: {
     
                title: '供应商',
                menu: "thirdPlat"
              }
            },
          ]
        }]

第三步 路由守卫中拦截 和添加动态路由可在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 {
     
          api.LoginInfo().then(res => {
     
            console.log(res, '11')
            roleList = res.data.roles
            store.commit('setRoleList', roleList)
            addRouter(asyncRouters, roleList)
          })
        }
        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)
          }
        })
      }
      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.asyncRouters, ...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>

可参考写法—vue 动态路由权限管理

你可能感兴趣的:(vue.js,python,javascript)