vue實(shí)現(xiàn)動態(tài)路由的詳細(xì)代碼示例
vue-router對象中的addRoutes,用它來動態(tài)添加路由配置
格式:
router.addRoutes([路由配置對象]) this.$router.addRoutes([路由配置對象])
舉個(gè)例子:
// 按鈕 <button @click="hAddRoute">addRoute</button> // 回調(diào) hAddRoute() { this.$router.addRoutes([{ path: '/abc', component: () => import('@/views/abc'), }]) },
我是以 vue-admin-template 為例,做如下演示:
在router/index.js中的路由配置中 只保留靜態(tài)路由(因?yàn)槲覀円獎(jiǎng)討B(tài)的添加))
const createRouter = () => new Router({ // mode: 'history', // require service support scrollBehavior: () => ({ y: 0 }), routes: [...constantRoutes] //因?yàn)橐獎(jiǎng)討B(tài)添加動態(tài)路由,所以這里只寫靜態(tài)路由 })
在permission.js中引入,并使用addRoutes動態(tài)添加
這個(gè)是 router 下的 index.js中定義的 靜態(tài)路由、動態(tài)路由
接下來來看 在permission.js中引入的內(nèi)容,
// 引入所有的動態(tài)路由表(未經(jīng)過篩選) + import router, { asyncRoutes } from '@/router' const whiteList = ['/login', '/404'] router.beforeEach(async(to, from, next) => { // 開啟進(jìn)度條 NProgress.start() // 獲取本地token 全局getter const token = store.getters.token if (token) { // 有token if (to.path === '/login') { next('/') } else { if (!store.getters.userId) { await store.dispatch('user/getUserInfo') // 改寫成動態(tài)添加的方式 + router.addRoutes(asyncRoutes) } next() } } else { // 沒有token if (whiteList.includes(to.path)) { next() } else { next('/login') } } // 結(jié)束進(jìn)度條 NProgress.done() })
如果我們希望在調(diào)用addRoutes方法之后,要路由數(shù)據(jù)立刻反映到菜單中,我們需要想一個(gè)額外的方法,思考一下,vue開發(fā)中,哪個(gè)技術(shù)可以保證響應(yīng)式特性還可以動態(tài)修改? vuex!
補(bǔ)充模塊,在src/store/modules下補(bǔ)充menu.js模塊 (定義vuex管理菜單數(shù)據(jù))
import { constantRoutes } from '@/router' export default { namespaced: true, // 公共數(shù)據(jù) state: { // 本地取一下token menuList: [] // 所有可以訪問的路由配置 }, mutations: { setMenuList(state, asyncRoutes) { console.log('asyncRoutes', asyncRoutes) //第二個(gè)參數(shù)是調(diào)用mutatains時(shí)傳過來的動態(tài)路由參數(shù) state.menuList = [...constantRoutes, ...asyncRoutes] } } }
當(dāng)然,要在 src/store/index.js 中注冊這個(gè)模塊
修改src/permission.js中的代碼
if (!store.getters.userId) { await store.dispatch('user/getUserInfo') // 動態(tài)添加可以訪問的路由設(shè)置 router.addRoutes(asyncRoutes) // 根據(jù)用戶實(shí)際能訪問幾個(gè)頁面來決定從整體8個(gè)路由設(shè)置 // 中,過濾中出來幾個(gè),然后保存到vuex中 ++ store.commit('menu/setMenuList', asyncRoutes) //把動態(tài)路由存入vuex中 }
在src\layout\components\Sidebar\index.vue文件中,修改
routes() { // 拿到的是一個(gè)完整的包含了靜態(tài)路由和動態(tài)路由的數(shù)據(jù)結(jié)構(gòu) return this.$store.state.menu.menuList }
上一步我們實(shí)現(xiàn)了: 1.把動態(tài)路由通過addRoutes動態(tài)添加到了路由系統(tǒng)里, 2. 把動態(tài)路由保存到vuex的menu中,
但是我們沒有和權(quán)限數(shù)據(jù)做搭配,接下來我們通過接口返回的權(quán)限數(shù)據(jù)對動態(tài)菜單做過濾處理,以確定完成菜單與用戶權(quán)限相關(guān)。
接下來就是 調(diào)接口,后端返給你菜單數(shù)據(jù):
用戶能訪問哪些頁面是通過actions獲取到的,只需要從action中返回即可
在permission.js中獲取action的返回值并過濾
if (!store.getters.userId) { // 有token,要去的不是login,就直接放行 // 進(jìn)一步獲取用戶信息 // 發(fā)ajax---派發(fā)action來做 const menus = await store.dispatch('user/getUserInfo') console.log('當(dāng)前用戶能訪問的頁面', menus) console.log('當(dāng)前系統(tǒng)功能中提供的所有的動態(tài)路由頁面是', asyncRoutes) // 根據(jù)本用戶實(shí)際的權(quán)限menus去 asyncRoutes 中做過濾,選出本用戶能訪問的頁面 const filterRoutes = asyncRoutes.filter(route => { const routeName = route.children[0].name return menus.includes(routeName) }) // 一定要在進(jìn)入主頁之前去獲取用戶信息 // addRoutes用來動態(tài)添加路由配置 // 只有在這里設(shè)置了補(bǔ)充了路由配置,才可能去訪問頁面 // 它們不會出現(xiàn)左側(cè) router.addRoutes(filterRoutes) // 把它們保存在vuex中,在src\layout\components\Sidebar\index.vue // 生成左側(cè)菜單時(shí),也應(yīng)該去vuex中拿 store.commit('menu/setMenuList', filterRoutes) }
問題
如果我們刷新瀏覽器,會發(fā)現(xiàn)跳到了404頁面
對于addRoute添加的路由,在刷新時(shí)會白屏
原因
現(xiàn)在我們的路由設(shè)置中的404頁處在中間位置而不是所有路由的末尾了。
解決
把404頁改到路由配置的最末尾就可以了
filterRoutes.push({ path: '*', redirect: '/404', hidden: true }) //解決刷新去404頁面
// 解決刷新出現(xiàn)的白屏bug next({ ...to, // next({ ...to })的目的,是保證路由添加完了再進(jìn)入頁面 (可以理解為重進(jìn)一次) replace: true // 重進(jìn)一次, 不保留重復(fù)歷史 })
效果如下:
總結(jié)
到此這篇關(guān)于vue實(shí)現(xiàn)動態(tài)路由的文章就介紹到這了,更多相關(guān)vue實(shí)現(xiàn)動態(tài)路由內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Vue實(shí)現(xiàn)動態(tài)路由的示例詳解
- Vue?Router動態(tài)路由實(shí)現(xiàn)實(shí)現(xiàn)更靈活的頁面交互
- vue3實(shí)現(xiàn)動態(tài)路由及菜單
- vue3動態(tài)路由+菜單欄的實(shí)現(xiàn)示例
- 在Vue3中實(shí)現(xiàn)動態(tài)路由的示例代碼
- Vue3動態(tài)路由(響應(yīng)式帶參數(shù)的路由)變更頁面不刷新的問題解決辦法
- 解決vue2+vue-router動態(tài)路由添加及路由刷新后消失問題
- Vue3+Vue Router實(shí)現(xiàn)動態(tài)路由導(dǎo)航的示例代碼
- 前端單獨(dú)實(shí)現(xiàn)vue動態(tài)路由的示例代碼
相關(guān)文章
關(guān)于vuex的數(shù)據(jù)持久化處理方式
這篇文章主要介紹了關(guān)于vuex的數(shù)據(jù)持久化處理方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10vue項(xiàng)目出現(xiàn)ERESOLVE could not resolve問題及解決
這篇文章主要介紹了vue項(xiàng)目出現(xiàn)ERESOLVE could not resolve問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10Vue向下滾動加載更多數(shù)據(jù)scroll案例詳解
這篇文章主要介紹了Vue向下滾動加載更多數(shù)據(jù)scroll案例詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08Vue利用AJAX請求獲取XML文件數(shù)據(jù)的操作方法
在現(xiàn)代Web開發(fā)中,從前端框架到后端API的交互是必不可少的一部分,Vue.js作為一個(gè)輕量級且功能強(qiáng)大的前端框架,支持多種方式與服務(wù)器通信,從而獲取或發(fā)送數(shù)據(jù),本文將詳細(xì)介紹如何在Vue.js項(xiàng)目中使用AJAX請求來獲取XML格式的數(shù)據(jù),需要的朋友可以參考下2024-09-09