动态路由和按钮权限

2022-07-11  本文已影响0人  冰点雨

静态路由

路由代码写死,所有路由不会根据角色进行改变

router->index.vue

export const constantRoutes = [
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },

  {
    path: '/404',
    component: () => import('@/views/404'),
    hidden: true
  },

  {
    path: '/',
    component: Layout,
    redirect: '/dashboard',
    children: [{
      path: 'dashboard',
      name: 'Dashboard',
      component: () => import('@/views/dashboard/index'),
      meta: { title: '首页', icon: 'dashboard' }
    }]
  },
 {
    path: '/manager',
    component: Layout,
    redirect: '/produce/table',
    name: 'Manager',
    meta: { title: '权限管理', icon: 'el-icon-goods' },
    children: [
      {
        path: 'user',
        name: 'User',
        component: () => import('@/views/manager/User/index'),
        meta: { title: '用户管理'}
      },
      {
        path: 'role',
        name: 'Role',
        component: () => import('@/views/manager/Role/index'),
        meta: { title: '角色管理'}
      },
      {
        path: 'pression',
        name: 'Pression',
        component: () => import('@/views/manager/Pression/index'),
        meta: { title: '菜单管理'}
      }
    ]
  },
  {
    path: '/product',
    component: Layout,
    redirect: '/produce/table',
    name: 'Produce',
    meta: { title: '商品管理', icon: 'el-icon-goods' },
    children: [
      {
        path: 'trademark',
        name: 'Trademark',
        component: () => import('@/views/product/Trademark/index'),
        meta: { title: '品牌管理'}
      },
      {
        path: 'attr',
        name: 'Attr',
        component: () => import('@/views/product/Attr/index'),
        meta: { title: '平台属性管理'}
      },
      {
        path: 'spu',
        name: 'Spu',
        component: () => import('@/views/product/Spu/index'),
        meta: { title: 'Spu管理'}
      },
      {
        path: 'sku',
        name: 'Sku',
        component: () => import('@/views/product/Sku/index'),
        meta: { title: 'Sku管理'}
      }
    ]
  },
]

用到路由的地方直接遍历

  routes() {
       return this.$router.options.routes
    },

动态路由

路由权限根据角色,进行不同的展示

1.路由编写

router->index.vue

// 常量路由:所有角色都可以看到
export const constantRoutes = [
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },

  {
    path: '/404',
    component: () => import('@/views/404'),
    hidden: true
  },

  {
    path: '/',
    component: Layout,
    redirect: '/dashboard',
    children: [{
      path: 'dashboard',
      name: 'Dashboard',
      component: () => import('@/views/dashboard/index'),
      meta: { title: '首页', icon: 'dashboard' }
    }]
  },
]


// 异步路由:要跟服务器返回的路径进行比较,筛选出要展示的路由
export const asyncRoutes = [
  {
    path: '/manager',
    component: Layout,
    redirect: '/produce/table',
    name: 'Manager',
    meta: { title: '权限管理', icon: 'el-icon-goods' },
    children: [
      {
        path: 'user',
        name: 'User',
        component: () => import('@/views/manager/User/index'),
        meta: { title: '用户管理'}
      },
      {
        path: 'role',
        name: 'Role',
        component: () => import('@/views/manager/Role/index'),
        meta: { title: '角色管理'}
      },
      {
        path: 'pression',
        name: 'Pression',
        component: () => import('@/views/manager/Pression/index'),
        meta: { title: '菜单管理'}
      }
    ]
  },
  {
    path: '/product',
    component: Layout,
    redirect: '/produce/table',
    name: 'Produce',
    meta: { title: '商品管理', icon: 'el-icon-goods' },
    children: [
      {
        path: 'trademark',
        name: 'Trademark',
        component: () => import('@/views/product/Trademark/index'),
        meta: { title: '品牌管理'}
      },
      {
        path: 'attr',
        name: 'Attr',
        component: () => import('@/views/product/Attr/index'),
        meta: { title: '平台属性管理'}
      },
      {
        path: 'spu',
        name: 'Spu',
        component: () => import('@/views/product/Spu/index'),
        meta: { title: 'Spu管理'}
      },
      {
        path: 'sku',
        name: 'Sku',
        component: () => import('@/views/product/Sku/index'),
        meta: { title: 'Sku管理'}
      }
    ]
  },
]


// 任意路由:页面出现错误,重定向404
//  404 page must be placed at the end !!!
export const anyRoute = { path: '*', redirect: '/404', hidden: true };

2.登录成功获取用户信息之后,根据后台返回路由进行路由处理

user.js

import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter,anyRoute,asyncRoutes,constantRoutes } from '@/router'
import router from '@/router'

const getDefaultState = () => {
  return {
    token: getToken(),
    name: '',
    avatar: '',
    routes:[],
    buttons:[],
    roles:[],
    // 计算出不同的角色需要展示的路由
    resultAsyncRoutes:[],
    // 用户需要展示的全部路由
    resultAllRoutes:[]
  }
}

const state = getDefaultState()

const mutations = {
  SET_USERINFO: (state, userInfo) => {
    state.name = userInfo.name;
    state.avatar = userInfo.avatar;
    state.routes = userInfo.routes;
    state.buttons = userInfo.buttons;
    state.roles = userInfo.roles;
  },
  SET_RESULTASYNCROUTES: (state, asyncRoutes) => {
    state.resultAsyncRoutes = asyncRoutes;
    state.resultAllRoutes =  constantRoutes.concat(state.resultAsyncRoutes,anyRoute);
    // 给路由器设置新的路由
    router.addRoutes(state.resultAllRoutes);
  }
}

const actions = {
  // get user info
  async getInfo({ commit, state }) {
    let result = await getInfo(state.token);
    if (result.code == 20000) {
      if (!result.data) {
        return Promise(new Error("Verification failed, please Login again."));
      }
      const { data } = result
      commit('SET_USERINFO', data);
      commit('SET_RESULTASYNCROUTES', computedResultRoutes(asyncRoutes,data.routes))
      return "ok";
    } else {
      return Promise(new Error("faile"));
    }
  },
}


// 根据服务器数据和本地路由,计算不同角色展示的路由
const computedResultRoutes = (asyncRoutes,routes)=>{
  // 过滤当前用户角色需要展示的异步路由
  return asyncRoutes.filter(item=>{
    // 数组当中没有这个原生返回值为-1,有这个元素返回值一定不是-1
    if(routes.indexOf(item.name) == -1){
      // 递归:会有多级路由的情况
       if(item.children && item.children.length){
         item.children =  computedResultRoutes(item.children,routes);
       }
       return true;
    }
  })
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

3.需要展示路由的页面

 routes() {
      return this.$store.state.user.resultAllRoutes
    },

按钮权限

1.配置异步路由

// 异步路由:要跟服务器返回的路径进行比较,筛选出要展示的路由
export const asyncRoutes = [
  {
    path: '/test',
    component: Layout,
    redirect: '/produce/table',
    name: 'Test',
    meta: { title: '测试管理', icon: 'el-icon-goods' },
    children: [
      {
        path: 'test1',
        name: 'Test1',
        component: () => import('@/views/test/test1/index'),
        meta: { title: '测试管理1'}
      },
      {
        path: 'test2',
        name: 'Test2',
        component: () => import('@/views/test/test2/index'),
        meta: { title: '测试管理2'}
      }
    ]
  },
]

需求: 根据用户角色动态展示按钮1、按钮2、按钮3,是否展示由接口返回

test1.vue

<template>
    <div id="">
        <el-button type="primary" v-show="$store.state.user.buttons.indexOf('btn.Add1') != -1">添加按钮1</el-button>
        <el-button type="primary" v-show="$store.state.user.buttons.indexOf('btn.Add2') != -1">添加按钮2</el-button>
    </div>
</template>

test2.vue

<template>
    <div id="">
        <el-button type="primary" v-show="$store.state.user.buttons.indexOf('btn.Add3') != -1">添加按钮3</el-button>
    </div>
</template>
上一篇下一篇

猜你喜欢

热点阅读