Vuejs 實現權限管理

程序運行時,router只配置登錄 首頁404 等基本頁面vue

複製代碼
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
];
複製代碼

 使用路由android

複製代碼
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中webpack

複製代碼
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;
                }
              }
            })

        }
      });
    },
複製代碼

返回格式:ios

複製代碼
{
    "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 在使用前 修改配置web

複製代碼
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中的menuListvue-router

複製代碼
<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="width: 70px;margin-left: -5px;padding:10px 0;" type="text">
                        <Icon :size="20" :color="iconColor" :type="item.icon"></Icon>
                    </Button>
                    <DropdownMenu style="width: 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="width: 70px;margin-left: -5px;padding:10px 0;" type="text">
                        <Icon :size="20" :color="iconColor" :type="item.icon"></Icon>
                    </Button>
                    <DropdownMenu style="width: 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中獲取從新賦值。vuex

相關文章
相關標籤/搜索