zoukankan      html  css  js  c++  java
  • Vuejs 实现权限管理

    程序运行时,router只配置登陆 首页404 等基本页面

    复制代码
    import Main from '@/views/Main.vue';
    
    // 不作为Main组件的子页面展示的页面单独写,如下
    export const loginRouter = {
        path: '/login',
        name: 'login',
        meta: {
            title: 'Login - 登录'
        },
        component: resolve => { require(['@/views/login.vue'], resolve); }
    };
    
    export const page404 = {
        path: '/*',
        name: 'error-404',
        meta: {
            title: '404-页面不存在'
        },
        component: resolve => { require(['@/views/error-page/404.vue'], resolve); }
    };
    
    export const page403 = {
        path: '/403',
        meta: {
            title: '403-权限不足'
        },
        name: 'error-403',
        component: resolve => { require(['@//views/error-page/403.vue'], resolve); }
    };
    
    export const page500 = {
        path: '/500',
        meta: {
            title: '500-服务端错误'
        },
        name: 'error-500',
        component: resolve => { require(['@/views/error-page/500.vue'], resolve); }
    };
    
    // 作为Main组件的子页面展示但是不在左侧菜单显示的路由写在otherRouter里
    export const otherRouter = {
        path: '/',
        component: Main,
        children: [
            { path: '/', title:'Home', name: 'home_index', component: resolve => { require(['@/views/page/home.vue'], resolve); } }
        ]
    };
    
    // 作为Main组件的子页面展示并且在左侧菜单显示的路由写在appRouter里
    export const appRouter = [];
    
    // 所有上面定义的路由都要写在下面的routers里
    export const routers = [
        loginRouter,
        otherRouter,
        ...appRouter,
        page500,
        page403
    ];
    复制代码

     使用路由

    复制代码
    import Vue from 'vue';
    import iView from 'iview';
    import Util from '../libs/util';
    import VueRouter from 'vue-router';
    import {routers,page404} from './router';
    import Cookies from 'js-cookie';
    import Main from '@/views/Main.vue';
    import store from '@/store';
    
    Vue.use(VueRouter);
    
    // 路由配置
    const RouterConfig = {
        // mode: 'history',
        routes: routers
    };
    
    export const router = new VueRouter(RouterConfig);
    
    
    router.beforeEach((to, from, next) => {
        iView.LoadingBar.start();
        Util.title(to.meta.title);
        if (!Cookies.get('user') && to.name !== 'login') {  // 判断是否已经登录且前往的页面不是登录页
            next({
                name: 'login'
            });
        } else if (Cookies.get('user') && to.name === 'login') {  // 判断是否已经登录且前往的是登录页
            Util.title();
            next({
                name: '/'
            });
        } else {
            next();
        }
    });
    
    router.afterEach((to) => {
        iView.LoadingBar.finish();
        window.scrollTo(0, 0);
    });
    复制代码

    登陆操作 获取菜单 将菜单存到sessionStorage中,并且把菜单存储到vuex中,因为vuex一刷新就没了,所以要放在sessionStorage中

    复制代码
    handleSubmit() {
          this.$refs.loginForm.validate((valid) => {
            if (valid) {
              this.$http.post('/api/login/login', this.form)
                .then((data) => {
                  this.submitPedding = false
                  if (data.result) {
                    window.sessionStorage.clear();
                    this.$http.get('/api/Common/GetMenuTree')
                      .then((data) => {
                        window.sessionStorage.routes = JSON.stringify(data)
                        this.$store.commit('updateMenulist', data)
                        // let routes = this.generateRoutesFromMenu(data)
                        // for(var i = 0;i<routes.length;i++){
                        //   this.$router.options.routes.push(routes[i]);
                        // }
                        // this.$router.addRoutes(this.$router.options.routes)
    
                        Cookies.set('user', this.form.userName);
                        this.$router.push({
                          path: '/'
                         });
                      })
                  } else {
                    switch (data.errorcode) {
                      case 1:
                        this.$Message.info({
                          content: '请输入您的账号',
                          duration: 10,
                          closable: true
                        });
                        break;
                      case 2:
                        this.$Message.info({
                          content: '请输入您的密码',
                          duration: 10,
                          closable: true
                        });
                        break;
                      case 3:
                        this.$Message.warning({
                          content: '用户名或密码错误',
                          duration: 10,
                          closable: true
                        });
                        break;
                      default:
                        this.$Message.info({
                          content: '登陆失败,请稍后再试',
                          duration: 10,
                          closable: true
                        });
                        break;
                    }
                  }
                })
    
            }
          });
        },
    复制代码

    返回格式:

    复制代码
    {
        "results": false,
        "code": 0,
        "msg": null,
        "sub_code": null,
        "sub_msg": null,
        "data": [{
            "path": "/ParcelReceiving",
            "icon": "earth",
            "title": "包裹收货",
            "component": null,
            "children": [{
                "path": "/ParcelReceiving/index",
                "title": "Page",
                "name": "opbgsh1",
                "component": "ParcelReceiving"
            }]
        }, {
            "path": "/ParcelProcessing",
            "icon": "social-buffer",
            "title": "包裹处理",
            "component": null,
            "children": [{
                "path": "/ParcelProcessing/index",
                "title": "Page",
                "name": "opbgcl1",
                "component": "ParcelProcessing"
            }]
        }, {
            "path": "/CustomsEditor",
            "icon": "clipboard",
            "title": "海关信息",
            "component": null,
            "children": [{
                "path": "/CustomsEditor/index",
                "title": "Page",
                "name": "ophgxx1",
                "component": "CustomsEditor"
            }]
        }, {
            "path": "/ParcelTransfer",
            "icon": "ios-infinite",
            "title": "包裹转单",
            "component": null,
            "children": [{
                "path": "/ParcelTransfer/index",
                "title": "Page",
                "name": "opbgzd1",
                "component": "ParcelTransfer"
            }]
        }, {
            "path": "/PackagingServices",
            "icon": "archive",
            "title": "打包封装",
            "component": null,
            "children": [{
                "path": "/PackagingServices/index",
                "title": "Page",
                "name": "opdbfz1",
                "component": "PackagingServices"
            }]
        }, {
            "path": "/ProblemPackageList",
            "icon": "alert-circled",
            "title": "问题包裹",
            "component": null,
            "children": [{
                "path": "/ProblemPackageList/index",
                "title": "Page",
                "name": "opwtbg1",
                "component": "ProblemPackageList"
            }]
        }, {
            "path": "/ParcelSearch",
            "icon": "search",
            "title": "包裹查询",
            "component": null,
            "children": [{
                "path": "/ParcelSearch/index",
                "title": "Page",
                "name": "opbgcx1",
                "component": "ParcelSearch"
            }]
        }, {
            "path": "/TrayInquire",
            "icon": "search",
            "title": "托盘查询",
            "component": null,
            "children": [{
                "path": "/TrayInquire/index",
                "title": "Page",
                "name": "optpcx1",
                "component": "TrayInquire"
            }]
        }, {
            "path": "/TransferLabel",
            "icon": "ios-infinite",
            "title": "转运单",
            "component": null,
            "children": [{
                "path": "/TransferLabel/index",
                "title": "Page",
                "name": "opbgzyd1",
                "component": "TransferLabel"
            }]
        }, {
            "path": "/CategoryName",
            "icon": "sad-outline",
            "title": "品类管理",
            "component": null,
            "children": [{
                "path": "/CategoryName/index",
                "title": "品类列表",
                "name": "opplgl1",
                "component": "CategoryName"
            }, {
                "path": "/CategoryName/Add",
                "title": "添加品类",
                "name": "opplgl2",
                "component": "CategoryNameAdd"
            }, {
                "path": "/CategoryName/Prohibited",
                "title": "禁运品名",
                "name": "opplgl3",
                "component": "ProhibitedCategory"
            }]
        }, {
            "path": "/SystemPlugs",
            "icon": "android-download",
            "title": "系统设置",
            "component": null,
            "children": [{
                "path": "/SystemPlugs/index",
                "title": "Page",
                "name": "opxtsz1",
                "component": "SystemPlugs"
            }]
        }]
    }
    复制代码

    其中component存储的是字符串 需要转换为引入 vue组件 修改router.index 在使用前 修改配置

    复制代码
    import Vue from 'vue';
    import iView from 'iview';
    import Util from '../libs/util';
    import VueRouter from 'vue-router';
    import {routers,page404} from './router';
    import Cookies from 'js-cookie';
    import Main from '@/views/Main.vue';
    import store from '@/store';
    
    Vue.use(VueRouter);
    
    // 路由配置
    const RouterConfig = {
        // mode: 'history',
        routes: routers
    };
    
    //避免刷新后 菜单清空
    let menus = window.sessionStorage.routes //登录成功返回的菜单
    if (menus != null && menus != "null" && menus.length != 0) {
      let items = JSON.parse(menus)
      store.commit('updateMenulist', items)
      let routes = generateRoutesFromMenu(items)
      for(var i = 0;i<routes.length;i++){
        routers.push(routes[i]);
      }
    }
    routers.push(page404)
    function generateRoutesFromMenu(menu = [], routes = []) {
      for (let i = 0; i < menu.length; i++) {
        menu[i].component = require('../views/Main.vue');
        for(let j = 0;j<menu[i].children.length;j++){
          let filePath = menu[i].children[j].component
          menu[i].children[j].component = require('../views/page/' + filePath + '.vue');
        }
        routes.push(menu[i])
      }
      return routes
    }
    export const router = new VueRouter(RouterConfig);
    
    
    router.beforeEach((to, from, next) => {
        iView.LoadingBar.start();
        Util.title(to.meta.title);
        if (!Cookies.get('user') && to.name !== 'login') {  // 判断是否已经登录且前往的页面不是登录页
            next({
                name: 'login'
            });
        } else if (Cookies.get('user') && to.name === 'login') {  // 判断是否已经登录且前往的是登录页
            Util.title();
            next({
                name: '/'
            });
        } else {
            next();
        }
    });
    
    router.afterEach((to) => {
        iView.LoadingBar.finish();
        window.scrollTo(0, 0);
    });
    复制代码
    menu[i].children[j].component = require('../views/page/' + filePath + '.vue'); 这里 前面的路径 和后面的.vue不可少,意思是让webpack到views下面的page下面去找.vue结尾的文件。
    404路由 要加到最后 否则路由先找到*的 以后的就不执行了。
    store中
    复制代码
    const app = {
        state: {
            menuList: [],
            routers: [
                otherRouter,
                ...appRouter
            ]
        },
        mutations: {
            updateMenulist (state,menu) {
                state.menuList = menu;
            }
        }
    };
    复制代码

    左侧菜单遍历 store中的menuList

    复制代码
    <template>
        <div>
            <template v-for="(item, index) in menuList">
                <div style="text-align: center;" :key="index">
                    <Dropdown transfer v-if="item.children.length !== 1" placement="right-start" :key="index" @on-click="changeMenu">
                        <Button style=" 70px;margin-left: -5px;padding:10px 0;" type="text">
                            <Icon :size="20" :color="iconColor" :type="item.icon"></Icon>
                        </Button>
                        <DropdownMenu style=" 200px;" slot="list">
                            <template v-for="(child, i) in item.children">
                                <DropdownItem :name="child.name" :key="i"><Icon :type="child.icon"></Icon><span style="padding-left:10px;">{{ itemTitle(child) }}</span></DropdownItem>
                            </template>
                        </DropdownMenu>
                    </Dropdown>
                    <Dropdown transfer v-else placement="right-start" :key="index" @on-click="changeMenu">
                        <Button @click="changeMenu(item.children[0].name)" style=" 70px;margin-left: -5px;padding:10px 0;" type="text">
                            <Icon :size="20" :color="iconColor" :type="item.icon"></Icon>
                        </Button>
                        <DropdownMenu style=" 200px;" slot="list">
                            <DropdownItem :name="item.children[0].name" :key="'d' + index"><Icon :type="item.icon"></Icon><span style="padding-left:10px;">{{ itemTitle(item.children[0]) }}</span></DropdownItem>
                        </DropdownMenu>
                    </Dropdown>
                </div>
            </template>
        </div>
    </template>
    复制代码

    至此 权限从后台读取,到前台页面展示就完成了,页面内部每次刷新 都会重新从sessionStorage中获取重新赋值。

  • 相关阅读:
    一周内签到连续天数求解
    int型动态数组总结
    快速排序总结
    希尔排序总结
    冒泡排序的总结
    桶排序总结
    插入排序的总结
    选择排序的总结
    二分法的五种实现
    安装Yum源
  • 原文地址:https://www.cnblogs.com/sweet-ice/p/10530754.html
Copyright © 2011-2022 走看看