美文网首页
动态路由和按钮权限

动态路由和按钮权限

作者: 冰点雨 | 来源:发表于2022-07-11 10:39 被阅读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>
    

    相关文章

      网友评论

          本文标题:动态路由和按钮权限

          本文链接:https://www.haomeiwen.com/subject/catnbrtx.html