VUE利用addRoutes實現動態加載路由

可能是源於VUE前端新手吧(沒辦法,誰讓公司沒有專業前端,只能寫後端的人硬着頭皮去實現),這個問題花了將近兩天的時間。最開始也是瘋狂百度,是個相關網頁都要去瞅一瞅,在這個過程中竟然有好多做出效果的都是參考花褲衩大神的,有興趣的同學可以去看下

我的代碼也是比葫蘆畫瓢,實現思路大致都是一樣的

1、路由表在初始化的時候先設置好一些公共路由如登錄頁面

2、利用v-for頁面動態加載左側菜單欄(因爲我們這個項目是login跳轉到首頁面system,在system組件mouted時axios獲得用戶的權限菜單,而這些菜單信息中含有組件名稱信息),我首先做的是把這些菜單信息整理成路由表(此時這裏存的component只是一個字符串)的格式並存儲到session裏邊

            <el-menu
                background-color="#245e9e"
                text-color="#fff"
                active-text-color="#ffd04b">
                <template v-for="(item,index) in Jurisdiction">
                    <el-submenu :index=item.id v-if="item.children">
                        <template slot="title">
                            <img :src="menuIcon[index]" class="menu-icon"/>
                            {{item.label}}
                        </template>
                        <el-menu-item :index=i.id v-for="(i,index) in item.children"  :key="index" @click="gotoPage(i.isSubSystem,i.url,i.label)">{{i.label}}</el-menu-item>
                    </el-submenu>
                    <el-menu-item  @click="gotoPage(item.isSubSystem,item.url,item.label)" :index=item.id v-else> <img :src="menuIcon[index]" class="menu-icon"/>{{item.label}}</el-menu-item>
                </template>
            </el-menu>
    saveRouteInfo(data){
          let myRouters = new Array();
          for (let i = 0;i < data.length;i++){
              if(data[i].children && data[i].children.length){
                  let cd = data[i].children;
                  for (let j = 0;j<cd.length;j++) {
                      let item = cd[j];
                      if (item.isSubSystem == '0' & item.url != '#') {
                          myRouters.push({name: item.url, path: item.url,  component:item.url});
                      }
                  }
              }

          }
        let routers = [{path: '/System',name: 'System',component: "System",children:myRouters}];
        window.sessionStorage.setItem("routeInfo", JSON.stringify(routers));
    }

3、router.beforeEach做完判斷後addRoutes(在這個過程中,還要將component轉化成組件形式)

完整router.js如下

import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from "../Login.vue"
import Home from "../App.vue"
import System from "../System"

Vue.use(VueRouter);
let constantRouterMap=[{
        path: '/Login',         //鏈接路徑
        name: 'Login',     //路由名稱,
        component: Login   //對應的組件模板
    },
    {
        path: '/systemIndex',
        name: 'systemIndex',
        component: System,
    },
    {
        path: '/home',
        name: 'Home',
        component: Home,
    }];

const router = new VueRouter({
    routes:constantRouterMap,
});
var getRouter; //用來獲取後臺拿到的路由
router.beforeEach((async(to, from, next) => {
    if (to.path == '/systemIndex'){
        next();
    }
    if (!getRouter){//要加一下這個判斷,要不然真的是死循環
        getRouter = JSON.parse(window.sessionStorage.getItem('routeInfo'));//拿到路由
        if (null != getRouter){
            router.addRoutes(filterAsyncRouter(getRouter));
            next({ ...to, replace: true });
        }
    }else {
        next();
    }

}));

function filterAsyncRouter(asyncRouterMap) { //遍歷後臺傳來的路由字符串,轉換爲組件對象
    const accessedRouters = asyncRouterMap.filter(route => {
        if (route.component == 'System') {
            route.component = System;
        }else{
            route.component = () => import('../modules/'+route.name+'.vue');
        }

        if (route.children && route.children.length) {
            route.children = filterAsyncRouter(route.children)
        }
        return true
    })
    return accessedRouters
}

export default router;

注:利用route.component = () => import('../modules/'+route.name+'.vue');這種形式轉換成組件,親測有效,之前也看過好多文章很麻煩我也沒看懂

後記:感覺想實現某種功能效果的過程中,就是一個不斷試錯的過程,好像頭破血流之後就知道哪裏可以這樣寫,哪裏不可以這樣寫,即便是網上參考別人的例子也很少有一次就能成功的。這個時候總會不自覺感嘆:

紙上得來終覺淺,絕知此事要躬行

你說對嗎?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章