router.addRoutes()設(shè)置動(dòng)態(tài),動(dòng)態(tài)路由對(duì)應(yīng)頁(yè)面直接刷新后無(wú)效vue-router-3.0.1 使用router.addRoutes()設(shè)置動(dòng)態(tài)路由,從非動(dòng)態(tài)路由(router初始化時(shí)就存在的路由)頁(yè)面跳轉(zhuǎn)到動(dòng)態(tài)添加的路由的頁(yè)面,一切正常。但是,在動(dòng)態(tài)添加的路由的頁(yè)面刷新后(即動(dòng)態(tài)路由對(duì)應(yīng)的頁(yè)面自己刷新再路由到自己),路由匹配失敗,頁(yè)面無(wú)法渲染。
最近做一個(gè)小項(xiàng)目,vue相關(guān)依賴版本如:
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"vuex": "^3.0.1"
項(xiàng)目中,用戶登錄系統(tǒng)前,初始默認(rèn)路由如下:
/**
* 靜態(tài)路由
*/
export const staticRouters = [{
path: '/',
redirect: '/Home'
}, {
path: '/Home',
component: Wrapper,
children: [{
path: '',
name: 'Home',
component: Home
}],
meta: {
name: '首頁(yè)'
}
}, {
path: '/DiscussZone',
component: Wrapper,
children: [{
path: '',
name: 'DiscussZone',
component: DiscussZone
}],
meta: {
name: '討論區(qū)'
}
}, {
path: '/Login',
name: 'Login',
component: Login
}, {
path: '/Register',
name: 'Register',
component: Register
}]
/**
* "個(gè)人中心" 子路由
*/
export const myCenterRouter = [{
path: '',
redirect: '/MyCenter/myGame'
}, {
path: 'myGame',
name: 'myGame',
component: MyGame,
meta: {
name: '我發(fā)布的比賽'
}
}, {
path: 'myPostings',
name: 'myPostings',
component: MyPostings,
meta: {
name: '我的帖子'
}
}]
/**
* 動(dòng)態(tài)路由
*/
export const dynamicRouters = [{
path: '/MyCenter',
component: Wrapper,
children: [{
path: '',
component: MyCenter,
children: myCenterRouter
}],
meta: {
name: '個(gè)人中心'
}
}, {
path: '*',
name: '404',
component: NotFound
}]
// 實(shí)例化初始靜態(tài)路由
export default new Router({
routes: staticRouters
})
在vux中,state中設(shè)置“用戶信息”userInfo字段,其中uid為用戶登錄唯一ID,getters中根據(jù)uid來(lái)計(jì)算用戶未登錄/登錄狀態(tài)下的可用功能模塊和動(dòng)態(tài)路由。
// vuex store/index.js
...
state: {
userInfo: {
uid: '',
role: ''
}
},
...
getters: {
// 計(jì)算用戶登陸后功能模塊
userStatusMenu: state => {
// 根據(jù)vuex中用戶id是否有值,判斷返回的功能菜單模塊
return !state.userInfo.uid ? state.staticMenuList : state.staticMenuList.concat(state.dynamicMenuList)
},
// 計(jì)算用戶登陸后動(dòng)態(tài)路由
userDynamicRouters: state => {
// 根據(jù)vuex中用戶id是否有值,判斷返回的動(dòng)態(tài)路由
return !state.userInfo.uid ? [] : dynamicRouters
}
},
mutations: {
// 保存/更新用戶信息
SET_USER_INFO(state, userInfo) {
// state.userInfo = Object.assign({}, state.userInfo, userInfo)
state.userInfo.uid = userInfo
}
},
用戶登錄前,系統(tǒng)菜單欄只有“首頁(yè)”、“討論區(qū)”兩個(gè)功能以及對(duì)應(yīng)的初始路由。當(dāng)用戶登錄系統(tǒng)后,動(dòng)態(tài)添加“個(gè)人中心”模塊和其對(duì)應(yīng)路由。
1.用戶登錄前,實(shí)例化“首頁(yè)”和“討論區(qū)”的初始路由
// router/index.js
...
export default new Router({
routes: staticRouters
})
...
2.當(dāng)用戶登錄系統(tǒng)后,將用戶uid寫入瀏覽器sessionStorage中(后面用戶強(qiáng)制刷新頁(yè)面時(shí),要使用其判斷),同時(shí)提交mutation,設(shè)置vuex中state的uesrInfo.uid字段,此時(shí),uid字段改變,便會(huì)重新計(jì)算getters中的用戶菜單欄(userStatusMenu),在系統(tǒng)菜單欄動(dòng)態(tài)添加“個(gè)人中心”模塊入口,并計(jì)算出該模塊的動(dòng)態(tài)新增的路由userDynamicRouters。
3.vuex中gettes計(jì)算求得需要?jiǎng)討B(tài)新增的路由userDynamicRouters后,使用router.addRoutes`(userDynamicRouters)添加動(dòng)態(tài)路由到初始化的路由實(shí)例對(duì)象router`。
login() {
this.$refs.loginForm.validate((valid) => {
if (valid) {
this.$store.commit('SET_USER_INFO', '1234567890') // 1.登陸成功,vuex設(shè)置用戶id
sessionStorage.setItem('userUuid', '1234567890') // 2.session同時(shí)存儲(chǔ)id,手動(dòng)刷新頁(yè)面時(shí)用它重寫vuex用戶id
this.$router.addRoutes(this.userDynamicRouters) // 3.追加動(dòng)態(tài)路由
this.$router.push('/Home') // 4.跳轉(zhuǎn)到首頁(yè)
} else {
this.$message.warning('請(qǐng)完善登錄信息!')
return false
}
})
}
至此,初步解決了根據(jù)用戶登錄狀態(tài)動(dòng)態(tài)生成系統(tǒng)菜單欄功能模塊入口和添加動(dòng)態(tài)路由功能。登陸后,動(dòng)態(tài)添加的“個(gè)人中心”模塊也可以正常路由。
但是系統(tǒng)頁(yè)面F5或者Ctrl+F5刷新后,因?yàn)樗⑿马?yè)面vuex和router實(shí)例會(huì)重新初始化到初始狀態(tài),所以vuex中state.userInfo.uid和新增的動(dòng)態(tài)路由會(huì)被刷掉。
所以,在main.js中設(shè)置全局路由守衛(wèi)router.beforeEach(),當(dāng)頁(yè)面刷新時(shí)重新判斷登錄時(shí)存儲(chǔ)的localStorage中uid字段,如果存在,說(shuō)明用戶登錄,此時(shí)如果vuex中state.userInfo.uid如果為空,說(shuō)明是用戶登錄后進(jìn)行了刷新頁(yè)面的操作,此時(shí)會(huì)重新向vuex提交mutation,設(shè)置state.userInfo.uid,并重新計(jì)算動(dòng)態(tài)路由,再addRotes()到路由實(shí)例router。如下:
// 路由跳轉(zhuǎn)前,登錄狀態(tài)判斷
router.beforeEach((to, from, next) => {
let userUid = sessionStorage.getItem('userUuid')
// sessionStorage中userUid不為空,說(shuō)明用戶已登錄
if (userUid) {
// vue中state.userInfo.uid為空,說(shuō)明用戶刷新了頁(yè)面
if (!store.state.userInfo.uid) {
store.commit('SET_USER_INFO', userUid) // 重新提交mutation,設(shè)置state.userInfo.uid
router.addRoutes(store.getters.userDynamicRouters) // 添加動(dòng)態(tài)路由
}
next()
} else {
// 沒(méi)有登錄信息,說(shuō)明沒(méi)有登錄
if (to.path.indexOf('/MyCenter') !== -1) {
next('/Home')
} else {
next()
}
}
});
至此解決了頁(yè)面刷新時(shí),動(dòng)態(tài)路由失效的問(wèn)題。
但是,But,However,我遇到了一個(gè)的坑,也是這篇帖子最后想問(wèn)的問(wèn)題??!前面交代那么多,就是想把自己實(shí)現(xiàn)的機(jī)制描述清楚,方便大神帶帶我,指導(dǎo)一下??!
這個(gè)坑是:我在“首頁(yè)”、“討論區(qū)”這種router初始化時(shí)就存在的模塊中點(diǎn)擊菜單跳轉(zhuǎn)到動(dòng)態(tài)路由模塊“個(gè)人中心”包括在這些頁(yè)面刷新頁(yè)面后再跳轉(zhuǎn)“個(gè)人中心”時(shí),一切路由都正常!But,但是,在進(jìn)入“個(gè)人中心”,也就是路由到動(dòng)態(tài)增加的動(dòng)態(tài)路由后,在動(dòng)態(tài)路由頁(yè)面直接刷新頁(yè)面,卻無(wú)法正常路由,頁(yè)面沒(méi)有渲染!!
找了半天,google,度娘找了一圈,也沒(méi)找到處理方法!小弟愚鈍,請(qǐng)大神賜教!!幫忙看看什么原因?
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國(guó)家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
北大課工場(chǎng)是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國(guó)家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國(guó)制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級(jí)產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國(guó)職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開(kāi)發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_(kāi)發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開(kāi)發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開(kāi)發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開(kāi)發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。