Vue3+Vite實現(xiàn)動態(tài)路由的詳細實例代碼
項目基本目錄
1.首先定義初始默認的路由routes(router.js文件),vue文件使用import引入可以按需加載
import { createRouter, createWebHashHistory } from "vue-router"; import store from '../store/index.js' const routes = [{ path: "/login", component: () => import("../view/Login/index.vue"), children: [], meta: { title: '登錄頁', hideMenu: true, //加入hideMenu屬性,不展示在側邊欄 }, name: "Login", }, { path: "/", component: () => import("../view/Home/index.vue"), meta: { keepalive: true, title: "主頁", }, name: 'Home', // hideMenu: true,//不展示在側邊欄 children: [], redirect: '/index' }, ]
2.在store的login.js模塊寫入調(diào)用后端數(shù)據(jù)的函數(shù)(寫在vuex的action對象中,方便全局異步調(diào)用)
Vuex 允許我們將 store 分割成模塊(module),比如登錄模塊,項目各個業(yè)務不相關的模塊。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊(具體可以看主頁另一篇博客)
3.執(zhí)行addRoutes函數(shù)獲取動態(tài)路由 (在router.js文件,點擊登錄成功后,在全局路由守衛(wèi)去判斷是否登錄成功,再調(diào)用addRoutes函數(shù))
(1)全局路由守衛(wèi)邏輯具體可看注釋,好處是進入項目之后,刷新頁面路由守衛(wèi)會攔截跳轉(zhuǎn),可以重新執(zhí)行addRoutes()獲取路由,先獲取動態(tài)路由,再執(zhí)行跳轉(zhuǎn),不然頁面會報本地路由找不到(一個小坑)
(代碼如下)
router.beforeEach(async (to, from, next) => { //路由守衛(wèi) if (store.state.login.token) { //存在token if (to.path == '/login') { //存在token,如果想跳轉(zhuǎn)到登錄頁,默認有token跳轉(zhuǎn)進項目首頁 next({ path: '/' }) } else { //如果存在token,跳轉(zhuǎn)進項目頁面,則判斷當前后端返回的路由有無長度 //或者有無即將跳轉(zhuǎn)路由的name if (store.getters['login/getRoutes'].length || to.name != null) { next() //有的話直接跳轉(zhuǎn) } else { //不滿足條件的話,重新請求后端動態(tài)路由數(shù)據(jù) await addRoutes(); //addRoutes()必須加入await!!!!等待邏輯執(zhí)行完畢獲取路由 // 如果 addRoute 未完成,路由守衛(wèi)會一層一層的執(zhí)行執(zhí)行,不加next()可能導致卡死! //直到 addRoute 完成,找到對應的路由 next({ ...to, replace: true }) } } } else { if (to.path == '/login') { next() } else { next('/login') } } })
后端返回的格式
(2)(重點在這,前面的步驟都可以不是重點)Vite使用import.meta.glob動態(tài)導入view文件夾所有前端頁面,并調(diào)用addRoutes()函數(shù)執(zhí)行獲取動態(tài)路由數(shù)據(jù)并做處理(代碼如下),主要作用是替換掉后端返回的component格式,再addRoute進路由表(看不懂的可以看代碼注釋或者可以搬進自己的項目打印看看每一步獲取的數(shù)據(jù))
let asyncRoutes = [] //定義數(shù)組接收后端返回的路由 const routeAllPathToCompMap =import.meta.glob(`../view/**/*.vue`); //**為通配符,vite不支持require導入方式,故用import.meta.glob(vite動態(tài)導入) /*import.meta.glob * 該方法匹配到的文件默認是懶加載,通過動態(tài)導入實現(xiàn),構建時會分離獨立的 chunk,是異步導入,返回的是 Promise * /*import.meta.globEager * 該方法是直接導入所有模塊,并且是同步導入,返回結果直接通過 for...in循環(huán)就可以操作 */ async function addRoutes() { await store.dispatch('login/getNewRoutes').then((res) => { //獲取后端返回的動態(tài)路由 if (res.data && res.data.length) { // let homeRouteChildren = []; asyncRoutes = res.data; /* * 1。拿到處理完畢home的children,最終替換掉原來的children,給菜單渲染提供支持 * 2.通過遞歸,調(diào)用router.addRoute,把每一項route插到對應的父route下 */ //服務端配置了路由,但前端還沒添加對應文件的路由列表,內(nèi)容是路由的component值(服務端的) // const unForList = [''] const homeChildren = routes[1].children; const dfs = (parentRouteName = 'Home', asyncRoutes = [], originRouteChildren = []) => { if (!Array.isArray(asyncRoutes)) return []; asyncRoutes.forEach(route => { // if (unForList.includes(route.component)) return; /**后端返回來的路由component是字符串,如component: "view/Index/index.vue", * 前端需要把component: "view/Index/index.vue" 轉(zhuǎn)化為組件對象 * component:() => import("/src/view/Index/index.vue") **/ route.component = routeAllPathToCompMap[`../${route.component}`]; // route.component = () => import(`../${route.component}`); const routeChildren = route.children; router.addRoute(parentRouteName, route); route.children = dfs(route.name, routeChildren) originRouteChildren.push(route) }) return originRouteChildren } // homeRouteChildren = dfs(asyncRoutes) dfs('Home', asyncRoutes, homeChildren) } }); }
最終轉(zhuǎn)化完成,路由數(shù)據(jù)格式如下
動態(tài)路由到此完成
總結
到此這篇關于Vue3+Vite實現(xiàn)動態(tài)路由的文章就介紹到這了,更多相關Vue3+Vite動態(tài)路由內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue中使用vue-pdf組件實現(xiàn)文件預覽及相應報錯解決
在需求中,經(jīng)常遇見pdf的在線預覽效果,很多pdf插件不支持vue3,或者是沒有集成翻頁放大縮小功能,比如vue-pdf,下面這篇文章主要給大家介紹了關于vue中使用vue-pdf組件實現(xiàn)文件預覽及相應報錯解決的相關資料,需要的朋友可以參考下2022-09-09