Vue iView Admin 動態路由菜單加載 先後端分離(springboot 2.x iview admin vue 先後端分離 模型設計器 動態數據權限


路由分爲兩種:一種存儲在本地文件中,大部分爲固定的頁面功能菜單;另外一種爲根據用戶角色動態加載的菜單包含相應按鈕權限信息。javascript

  • 固定路由菜單在文件src/router/router.js
  • 動態路由加載方法主要在文件src/libs/util.js中,主要經過router.addRoutes(routes)實現路由動態添加
util.initRouter = function (vm) {
    const constRoutes = [];
    const otherRoutes = [];

    // 404路由須要和動態路由一塊兒加載
    const otherRouter = [{
        path: '/*',
        name: 'error-404',
        meta: {
            title: '404-頁面不存在'
        },
        component: 'error-page/404'
    }];

    // 判斷用戶是否登陸
    let userInfo = Cookies.get('userInfo')
    if (userInfo == null || userInfo == "" || userInfo == undefined) {
        // 未登陸
        return;
    }
    let accessToken = window.localStorage.getItem('accessToken')
    // 加載菜單
    axios.get(getMenuList, { headers: { 'accessToken': accessToken } }).then(res => {
        let menuData = res.result;
        if (menuData == null || menuData == "" || menuData == undefined) {
            return;
        }
        // 頂部菜單
        let navList = [];
        menuData.forEach(e => {
            let nav = {
                name: e.name,
                title: e.title,
                icon: e.icon
            }
            navList.push(nav);
        })
        if (navList.length < 1) {
            return;
        }
        // 存入vuex
        vm.$store.commit('setNavList', navList);
        let currNav = window.localStorage.getItem('currNav')
        if (currNav) {
            // 讀取緩存title
            for (var item of navList) {
                if (item.name == currNav) {
                    vm.$store.commit('setCurrNavTitle', item.title);
                    break;
                }
            }
        } else {
            // 默認第一個
            currNav = navList[0].name;
            vm.$store.commit('setCurrNavTitle', navList[0].title);
        }
        vm.$store.commit('setCurrNav', currNav);
        for (var item of menuData) {
            if (item.name == currNav) {
                // 過濾
                menuData = item.children;
                break;
            }
        }
        util.initRouterNode(constRoutes, menuData);
        util.initRouterNode(otherRoutes, otherRouter);
        // 添加主界面路由
        vm.$store.commit('updateAppRouter', constRoutes.filter(item => item.children.length > 0));
        // 添加全局路由
        vm.$store.commit('updateDefaultRouter', otherRoutes);
        // 刷新界面菜單
        vm.$store.commit('updateMenulist', constRoutes.filter(item => item.children.length > 0));

        let tagsList = [];
        vm.$store.state.app.routers.map((item) => {
            if (item.children.length <= 1) {
                tagsList.push(item.children[0]);
            } else {
                tagsList.push(...item.children);
            }
        });
        vm.$store.commit('setTagsList', tagsList);
    });
};

// 生成路由節點
util.initRouterNode = function (routers, data) {

    for (var item of data) {
        let menu = Object.assign({}, item);
        // menu.component = import(`@/views/${menu.component}.vue`);
        menu.component = lazyLoading(menu.component);

        if (item.children && item.children.length > 0) {
            menu.children = [];
            util.initRouterNode(menu.children, item.children);
        }

        let meta = {};
        // 給頁面添加權限、標題、第三方網頁連接
        meta.permTypes = menu.permTypes ? menu.permTypes : null;
        meta.title = menu.title ? menu.title + " - XBoot先後端分離開發平臺 By: Exrick" : null;
        meta.url = menu.url ? menu.url : null;
        menu.meta = meta;

        routers.push(menu);
    }
};
複製代碼

注意:404路由須要和動態路由一塊兒加載,避免直接訪問動態路由路徑連接進入頁面時,動態路由還未加載致使先跳轉到404錯誤頁vue

  • 加載組件src/libs/lazyLoading.js
export  default (url) \=>()\=>import(`@/views/${url}.vue`)
複製代碼
  • 存入Vuex
// 動態添加主界面路由,須要緩存
updateAppRouter(state, routes) {
    state.routers.push(...routes);
    router.addRoutes(routes);
},
// 動態添加全局路由40四、500等頁面,不須要緩存
updateDefaultRouter(state, routes) {
    router.addRoutes(routes);
}
updateMenulist(state, routes) {
    state.menuList  =  routes;
},
複製代碼
  • src/main.js中進行調用
new Vue({
    el: '#app',
    render: h => h(App),
    mounted() {
        // 初始化菜單
        util.initRouter(this);
    }
})
複製代碼
相關文章
相關標籤/搜索