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