zoukankan      html  css  js  c++  java
  • vue 权限管理


    核心想法:

    登陆后获得用户角色,通过角色获得用户的权限,注入权限对应的路由。刷新页面,从localStorage用角色(更好的方式是通过token)再次获得所属权限,再次注入路由。在管理界面左端循环权限对应的路由菜单
    localStorage存用户的信息(token),权限路由不会存。

    所有的路由分为2种:
    • 公共路由:所有用户可以查看。
    • 权限路由:当前用户权限所属的路由。
    实现控制的方式分两种:
    • 通过 vue-router addRoutes 方法注入路由实现控制
    • 通过 vue-router beforeEach 钩子限制路由跳转
    一般来讲,需要采用第一种方式,addRoutes注入的方式,第二种每次判断,开销比较大,而且一次性拿不到角色对应的所有路由列表。这个列表需要再登陆后立即渲染在左边。



    权限的控制分为好几种:
    • 一级菜单的权限控制,
    • 二级菜单的权限控制,
    • 按钮级别的权限控制。
    控制方式有2种:
    • 后端返回路由控制列表
    • 前后端约定路由控制列表

    代码:一级菜单的权限控制,前后端约定的方式确定角色能访问的路由。
    routers/index.js

     

    import Vue from 'vue'
    import Router from 'vue-router'
    import loginRoute from './modules/login.js';
    import homeRoute from './modules/home.js'
    import productionRoute from './modules/production.js';
    import store from '../stores/index.js';
    
    
    Vue.use(Router)
    
    //不需要权限的路由
    export const constantRoutes = [loginRoute];
    //需要权限的路由
    //这里只是导出。实际上添加到router里在在store的permission里
    export const asyncRoutes = [
        homeRoute,
        productionRoute,
    ];
    console.log(asyncRoutes);
    const router = new Router({
        mode: 'history',
        base: process.env.BASE_URL,
        routes: [
            ...constantRoutes,
        ]
    })
    router.beforeEach((to,from,next)=>{
        let user = store.state.user.user;
        let permissionRoutes= store.state.permission.permissionRoutes;
        console.log(store.state);
        console.log(user);
        if(!user && to.path!=='/'){
            next({
                path:'/'
            });
        }else{
            //刷新页面的情况
            if(!permissionRoutes && user){
                store.dispatch('generateRoutes',{
                    role:user.role
                })
    
                console.log(router);
                console.log(to);
                //这里写next没用
                next({...to})
            }else{
                next();
            }
    
    
            // next({...to, replace: true })
        }
    });
    export default  router;
    

      其中,productionRoute:

    import Layout from '../../layouts/Index.vue'
    const productionAdd = () => import('../../pages/production/Add.vue')
    const productionList = () => import('../../pages/production/List.vue')
    const productionTemplateComplete  = () => import('../../pages/production/TemplateComplete.vue')
    let routes = {
        path: '/production',
        component: Layout,
        meta: {
            title: '产品管理',
            roles: [0, 1]
        },
        children: [
            {
                path: 'add',
                component: productionAdd,
                beforeEnter (to, from, next) {
                    console.log('router beforeEnter');
                    next();
                },
                meta: {
                    title: '产品新增'
                }
            },
            {
                path: 'list',
                component: productionList,
                meta: {
                    title: '产品列表'
                }
            },
            {
                path: 'templateComplete',
                component: productionTemplateComplete,
                meta: {
                    title: '产品新增完善'
                }
            }
        ]
    }
    
    export default routes
    

      

    stores/index.js
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    import user from './modules/user.js'
    import permission from './modules/permission.js'
    
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
        modules: {
            user,
            permission,
        }
    })
    

      



    stores/modules/user.js
    const SET_USER = 'SET_USER' //登录成功
    const CLEAR_USER = 'CLEAR_USER' //退出登录
    import $ajax from '../../axios/index.js';
    import store from '../index.js';
    export default {
        state: {
            user:JSON.parse(localStorage.getItem('user')) || null
        },
        mutations: {
            [SET_USER](state, user) {
                state.user = user;
                localStorage.setItem('user', JSON.stringify(user))
            },
    
            [CLEAR_USER](state) {
                state.user = null;
                localStorage.removeItem('user');
            }
        },
        actions: {
            login({commit}, param) {
                console.log('action');
                console.log(param);
                return new Promise((resolve, reject) => {
                    //一期不做后台登陆,前端判断
                    // $ajax({
                    //     url:api.login,
                    //     data:{
                    //         ...param
                    //     }
                    // }).then(res=>{
                    //     let user = res.data.data;
                    //     commit(SET_USER, user);
                    //     resolve();
                    // }).catch(res=>{
                    //     reject();
                    // })
                    //前端验证用户名,密码
                    window.setTimeout(()=>{
                        if(param.username === 'huainanju' && param.password === 'huainanju123'){
                            let user = {
                                username:'管理员',
                                role:0
                            }
                            commit(SET_USER, user);
                            store.dispatch('generateRoutes',{
                                role:user.role
                            })
                            resolve();
                        }else{
                            reject();
                        }
                    },1000)
                });
            },
            logout({commit}) {
                commit(CLEAR_USER)
            }
        }
    }
    

      



    stores/modules/permisson.js
    import {asyncRoutes} from '../../routers/index';
    import router from '../../routers/index';
    /**
     * 递归过滤异步路由表,返回符合用户角色权限的路由表
     * @param role
     */
    function filterAsyncRoutes(role) {
        const res = asyncRoutes.filter(route => {
            return route.meta.roles.includes(role)
        });
        return res
    }
    
    const permisssion = {
        state:{
            permissionRoutes:null
        },
        getter:{
    
        },
        mutations:{
            SET_ROUTERS: (state, routes) => {
                //添加路由
                console.log('添加路由');
                router.addRoutes(routes);
                state.permissionRoutes = routes // 权限路由
            },
        },
        actions:{
            generateRoutes({ commit }, data) {
                let {role} = data;
                let routes = filterAsyncRoutes(role);
                console.log(routes);
                commit('SET_ROUTERS', routes)
            }
        }
    }
    
    export default permisssion;
    

      

    layouts/Left.vue

    <template>
        <el-aside style="min-height:100%;min-250px;" width="250px">
            <el-menu :default-active="defaultActive"
                     background-color="#324157"
                     text-color="#bfcbd9"
                     active-text-color="#409EFF"
                     style="position:fixed;top:0;left:0;min-height: 100%;250px;z-index:100"
                     router>
                <template v-for="(item,index) in permissionRoutes">
                    <!--一级菜单-->
                    <el-menu-item :index="item.path" v-if="item.children.length === 1 ">
                        <i class="el-icon-menu"></i>
    <!--                    <div>我是</div>-->
                        <span>{{item.meta.title}}</span>
                    </el-menu-item>
                    <!--多级菜单-->
                    <el-submenu :index="index+''" v-else>
                        <template slot="title">
                            <i class="el-icon-menu"></i>
                            <span>{{item.meta.title}}</span>
                        </template>
                        <template v-for="child in item.children">
                            <el-menu-item :index="item.path+'/'+child.path">{{child.meta.title}}</el-menu-item>
                        </template>
                    </el-submenu>
                </template>
            </el-menu>
        </el-aside>
    </template>
    <script>
        import {mapState} from 'vuex'
    
        export default {
            data() {
                return {
                }
            },
            computed: {
                ...mapState({
                    'permissionRoutes':state=>state.permission.permissionRoutes
                }),
                defaultActive: function () {
                    if (this.$route.path.indexOf('/classInfo') >= 0) {
                        return 'classList'
                    }
                    return this.$route.path.replace('/org/', '');
                }
            },
            created() {
                window.setTimeout(()=>{
                    console.log(this.permissionRoutes);
                },1000)
            }
        }
    </script>
    

      










  • 相关阅读:
    MyBatis学习(一)
    ORM框架
    Java 核心技术点之注解
    git 分支 合并
    TensorFlow——零碎语法知识点
    TensorFlow——深入MNIST
    tensorflow——MNIST机器学习入门
    TensorFlow——小练习:feed
    TensorFlow——小练习:counter
    TensorFlow——交互式使用会话:InteractiveSession类
  • 原文地址:https://www.cnblogs.com/xiaochongchong/p/11308770.html
Copyright © 2011-2022 走看看