github上關(guān)于vue動態(tài)添加路由的例子很多,本項目參考了部分項目后,在iview框架基礎(chǔ)上完成了動態(tài)路由的動態(tài)添加和菜單刷新。為了幫助其他需要的朋友,現(xiàn)分享出實現(xiàn)邏輯,歡迎一起交流學(xué)習(xí)。
Github地址
iview-dynamicRouter
實現(xiàn)目標(biāo)
客戶端從服務(wù)端拿到路由和權(quán)限數(shù)據(jù)后,刷新項目的路由和菜單列表,并進(jìn)行權(quán)限控制。
項目基礎(chǔ)
基礎(chǔ)框架: iview組件庫官方模板項目 iview-admin 的template分支項目,此項目為 iview-admin 的基礎(chǔ)框架代碼。項目地址:iview-admin實現(xiàn)邏輯
動態(tài)路由控制加載
一般來說,動態(tài)路由控制分為兩種:一種是將所有路由數(shù)據(jù)存儲在本地文件中,然后從服務(wù)端獲取用戶的權(quán)限信息,在路由跳轉(zhuǎn)時,添加權(quán)限判斷鉤子,如果用戶前往的頁面不在權(quán)限列表內(nèi),則禁止跳轉(zhuǎn)。另一種則是本地只存儲基本路由,如錯誤處理頁面、無權(quán)限控制頁面等,而權(quán)限路由則從服務(wù)器獲取,服務(wù)器根據(jù)用戶的權(quán)限下發(fā)相應(yīng)的路由數(shù)據(jù),客戶端利用這些數(shù)據(jù)進(jìn)行路由的動態(tài)生成和添加,本文采用的是第二種方法。
iview-admin項目將路由分為三種:
不作為Main組件的子頁面展示的頁面路由,例如login、404、403等錯誤頁面路由; 作為Main組件的子頁面展示但是不在左側(cè)菜單顯示的路由 otherRouter ,比如首頁路由; 作為Main組件的子頁面展示并且在左側(cè)菜單顯示的路由 appRouter ;拿到路由數(shù)據(jù)后,我們主要進(jìn)行兩部分操作,第一部分是遍歷數(shù)據(jù),利用組件異步加載的方法,加載每個路由節(jié)點對應(yīng)的組件,之后利用 router.addRoutes(routes) 完成路由列表的動態(tài)添加;第二部分是因為 iview-admin 框架下的頁面標(biāo)簽和面包屑導(dǎo)航,需要遍歷appRouter獲取路由信息,所以我們也需要將路由數(shù)據(jù)存入 vuex ,以便全局訪問。
需要特別注意的是,如果404頁面為靜態(tài)路由,那么第一次進(jìn)入頁面時,這時動態(tài)路由還未加載,找不到路由地址會默認(rèn)跳轉(zhuǎn)到404錯誤頁,體驗很差,所以404路由先不寫入路由規(guī)則中,和動態(tài)路由一起加載。
主要代碼實現(xiàn)如下:
數(shù)據(jù)請求及路由節(jié)點生成
//util.js//生成路由util.initRouter = function (vm) { const constRoutes = []; const otherRoutes = []; // 404路由需要和動態(tài)路由一起注入 const otherRouter = [{ path: '/*', name: 'error-404', meta: { title: '404-頁面不存在' }, component: 'error-page/404' }]; // 模擬異步請求 util.ajax('menu.json').then(res => { var menuData = res.data; 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)); });};//生成路由節(jié)點util.initRouterNode = function (routers, data) { for (var item of data) { let menu = Object.assign({}, item); menu.component = lazyLoading(menu.component); if (item.children && item.children.length > 0) { menu.children = []; util.initRouterNode(menu.children, item.children); } //添加權(quán)限判斷 meta.permission = menu.permission ? menu.permission : null; //添加標(biāo)題 meta.title = menu.title ? menu.title : null; menu.meta = meta; }};
新聞熱點
疑難解答
圖片精選