
vue-router對象中的addRoutes,用它來動態(tài)添加路由配置
格式:
router.addRoutes([路由配置對象])
this.$router.addRoutes([路由配置對象])
舉個例子:
// 按鈕
<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)路由(因為我們要動態(tài)的添加))
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: [...constantRoutes] //因為要動態(tài)添加動態(tài)路由,所以這里只寫靜態(tài)路由
})
在permission.js中引入,并使用addRoutes動態(tài)添加
這個是 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) => {
// 開啟進度條
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é)束進度條
NProgress.done()
})
如果我們希望在調(diào)用addRoutes方法之后,要路由數(shù)據(jù)立刻反映到菜單中,我們需要想一個額外的方法,思考一下,vue開發(fā)中,哪個技術(shù)可以保證響應(yīng)式特性還可以動態(tài)修改? vuex!
補充模塊,在src/store/modules下補充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) //第二個參數(shù)是調(diào)用mutatains時傳過來的動態(tài)路由參數(shù)
state.menuList = [...constantRoutes, ...asyncRoutes]
}
}
}
當然,要在 src/store/index.js 中注冊這個模塊

修改src/permission.js中的代碼
if (!store.getters.userId) {
await store.dispatch('user/getUserInfo')
// 動態(tài)添加可以訪問的路由設(shè)置
router.addRoutes(asyncRoutes)
// 根據(jù)用戶實際能訪問幾個頁面來決定從整體8個路由設(shè)置
// 中,過濾中出來幾個,然后保存到vuex中
++ store.commit('menu/setMenuList', asyncRoutes) //把動態(tài)路由存入vuex中
}
在src\layout\components\Sidebar\index.vue文件中,修改
routes() {
// 拿到的是一個完整的包含了靜態(tài)路由和動態(tài)路由的數(shù)據(jù)結(jié)構(gòu)
return this.$store.state.menu.menuList
}
上一步我們實現(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,就直接放行
// 進一步獲取用戶信息
// 發(fā)ajax---派發(fā)action來做
const menus = await store.dispatch('user/getUserInfo')
console.log('當前用戶能訪問的頁面', menus)
console.log('當前系統(tǒng)功能中提供的所有的動態(tài)路由頁面是', asyncRoutes)
// 根據(jù)本用戶實際的權(quán)限menus去 asyncRoutes 中做過濾,選出本用戶能訪問的頁面
const filterRoutes = asyncRoutes.filter(route => {
const routeName = route.children[0].name
return menus.includes(routeName)
})
// 一定要在進入主頁之前去獲取用戶信息
// addRoutes用來動態(tài)添加路由配置
// 只有在這里設(shè)置了補充了路由配置,才可能去訪問頁面
// 它們不會出現(xiàn)左側(cè)
router.addRoutes(filterRoutes)
// 把它們保存在vuex中,在src\layout\components\Sidebar\index.vue
// 生成左側(cè)菜單時,也應(yīng)該去vuex中拿
store.commit('menu/setMenuList', filterRoutes)
}

問題
如果我們刷新瀏覽器,會發(fā)現(xiàn)跳到了404頁面
對于addRoute添加的路由,在刷新時會白屏
原因
現(xiàn)在我們的路由設(shè)置中的404頁處在中間位置而不是所有路由的末尾了。
解決
把404頁改到路由配置的最末尾就可以了文章來源:http://www.zghlxwxcb.cn/news/detail-791299.html

filterRoutes.push({ path: '*', redirect: '/404', hidden: true })
//解決刷新去404頁面
// 解決刷新出現(xiàn)的白屏bug
next({
...to, // next({ ...to })的目的,是保證路由添加完了再進入頁面 (可以理解為重進一次)
replace: true // 重進一次, 不保留重復歷史
})
效果如下:文章來源地址http://www.zghlxwxcb.cn/news/detail-791299.html

到了這里,關(guān)于vue 實現(xiàn)動態(tài)路由的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!