路由拦截与角色权限

故心故心故心故心小故冲啊



路由拦截

//分析
// 当前是否在登录页面  =>在=>放行
// 不在 =>没有登录或者已经登录了的

// 已经登录了(有角色信息的) =>放行
// 已经登录了(没有角色信息==>进行了刷新操作(或者第一次进去))=> 获取角色信息

// 没有登录的 =>返回登录页

router.beforeEach(async (to, from, next) => {
    //判断当前是否在登录页面
    if (to.path == '/login') {
        // 如果在=>放行
        // console.log('在登录页,直接放行');
        next();
    }
    //如果不在
    else {
        // 判断是否有角色信息(因为有可能是已经登录进来的了) 看是否能在store中获取到角色信息
        var R = store && store.getters.roles && store.getters.roles.length > 0;
        if (R) {
            //有角色 => 放行
            // console.log('有角色');
            next();
        }
        //没有角色呢?
        else {
            // 没有就获取角色---用户进行了刷新操作
            //获取角色 通通actions 发送请求获取 await需要获取到角色后在进行下面操作
            var { role_name } = await store.dispatch('userInfo');
            console.log(role_name);
            //2.0vuex来处理路由,把角色名传过去
            let asyncRoutes = await store.dispatch('GETROUTES', [role_name]);
            //3.0动态添加路由(asyncRoutes表示经过不同角色的路由)
            router.addRoutes(asyncRoutes);
            //若是获取到角色
            if (role_name) {
                next();
            }
            //若是获取不到角色
            else {
                // console.log('无角色信息,返回登录页');
                //无角色信息,返回登录页
                next({ path: '/login' })
            }
        }
    }
})

存储角色信息–vuex

import Vue from 'vue'
import Vuex from 'vuex'
import { userInfo, logout } from '@/api/interface'

Vue.use(Vuex)

const state = {
    //存储角色信息的
    roles: []
};
const getters = {
    //获取state中roles
    roles: state => state.roles
};
const mutations = {
    //同步的mutations 专门用于修改state中的状态
    //data就是actions中data中获取的角色信息的
    setRoles: (state, data) => state.roles = data

};
const actions = {
    //异步的  通过$store.dispath('actions名字')获取
    //登录
    userInfo({ commit }) {
        return new Promise((resolve, reject) => {
            //发送请求获取角色信息(用户详情)
            userInfo().then(res => {
                console.log(res);
                let { data } = res.data.data;
                //只能通过mutations来改变状态
                commit('setRoles', data[0][0].role_name)
                // console.log(data[0][0]);
                resolve(data[0][0]);
            }).catch(err => {
                reject(err);
            })
        })
    },
    // 退出 需要清除角色信息
    logout({ commit }) {
        return new Promise((resolve, reject) => {
            //发送请求获取角色信息(用户详情)
            logout().then(() => {
                //设置为空 ,清除
                commit('setRoles', [])
                resolve();
            }).catch(err => {
                reject(err);
            })
        })
    }


};

export default {
    state,
    getters,
    mutations,
    actions
}

通过角色信息动态添加路由

import Vue from 'vue'
import Vuex from 'vuex'
//引入常规路由配置 和 动态路由配置
import { constantRoutes, asyncRoutes } from '@/router'

Vue.use(Vuex)

function filterAsyncRouter(asyncRoutes, rolesName) {
    var filterRouter = asyncRoutes.filter(item => {
        //通过判断不是拥有该角色,来过滤出对应的路由
        return item.meta && item.meta.roles && rolesName.some(v => item.meta.roles.includes(v))
    })
    return filterRouter;
}

const state = {
    //这个是经过处理的路由,不同角色所产生的的路由
    routes: [],
};
const getters = {
    routes: state => state.routes
};
const actions = {
    //异步操作 =>需求不同角色所产生的的路由
    GETROUTES({ commit }, rolesName) {
        return new Promise((resolve) => {
            // console.log(constantRoutes);
            //1.0获取到home
            var _routes = []; //接收home
            var home = constantRoutes.filter(v => v.path == '/home')[0];
            //清除home的children
            home.children = []; //清除
            //2.0为home添加children(需要判断当前角色)
            if (rolesName.includes('administrator')) { //是否是管理员
                //是管理员,那动态配置所有路由
                console.log('管理员');
                home.children = asyncRoutes;
            } else {
                //不是管理员
                //通过角色过滤出路由
                console.log('非管理员');
                let filterRouter = filterAsyncRouter(asyncRoutes, rolesName);
                console.log(filterRouter);
                
                home.children = filterRouter;
            }
            //因为addRouter接受的参数是一个数组
            _routes = [home] || [];
            console.log(_routes)
            commit('SET_ROUTES', _routes);
            resolve(_routes);

        })
    }

};
const mutations = {
    //把从actions获得的路由修改state中的路由
    SET_ROUTES: (state, routes) => state.routes = routes
};

export default {
    state,
    getters,
    actions,
    mutations
}

通过vuex存储的路由信息来动态渲染路由

引入了子组件navItem 通过:item="route 实行渲染
index.vue

<template>
  <!-- 侧边导航栏 -->
  <el-aside width="200px">
    <el-menu default-active="$route.path" router exact text-color="#fff" active-text-color="skybule" unique-opened collapse-transition> 
      <navItem v-for="route in routes[0].children" :key="route.path" :item="route" />
    </el-menu>
  </el-aside>
</template>

<script>
import { mapGetters } from "vuex";
import navItem from "./navItem";
export default {
  computed: {
    ...mapGetters(["routes"])
  },
  components: {
    navItem
  }
};
</script>

navItem.vue

<template>
  <div>
    <el-menu-item :index="item.path" v-if="!item.children">
      <span slot="title">{{item.meta.title}}</span>
    </el-menu-item>

    <!-- 有子级 -->
    <el-submenu :index="item.path" v-else>
      <template slot="title">
        <span slot="title">{{item.meta.title}}</span>
      </template>
      <navItem v-for="child in item.children" :key="child.path" :item="child" />
    </el-submenu>
  </div>
</template>

<script>
export default {
  name: "navItem",
  props: ["item"]
};
</script>
<style scoped>
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值