在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問(wèn)答/HTML/ Vue-router-3.0.1 使用router.addRoutes()設(shè)置動(dòng)

Vue-router-3.0.1 使用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)路由對(duì)應(yīng)頁(yè)面直接刷新后無(wú)效

問(wèn)題總述

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ú)法渲染。

詳細(xì)介紹

最近做一個(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
    }
},

現(xiàn)在要實(shí)現(xiàn)如下功能:

用戶登錄前,系統(tǒng)菜單欄只有“首頁(yè)”、“討論區(qū)”兩個(gè)功能以及對(duì)應(yīng)的初始路由。當(dāng)用戶登錄系統(tǒng)后,動(dòng)態(tài)添加“個(gè)人中心”模塊和其對(duì)應(yīng)路由。

個(gè)人實(shí)現(xiàn)機(jī)制如下:

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.vuexgettes計(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è)面vuexrouter實(shí)例會(huì)重新初始化到初始狀態(tài),所以vuexstate.userInfo.uid和新增的動(dòng)態(tài)路由會(huì)被刷掉。

所以,在main.js中設(shè)置全局路由守衛(wèi)router.beforeEach(),當(dāng)頁(yè)面刷新時(shí)重新判斷登錄時(shí)存儲(chǔ)的localStorageuid字段,如果存在,說(shuō)明用戶登錄,此時(shí)如果vuexstate.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)一下??!

我遇到的坑和問(wèn)題

這個(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)大神賜教!!幫忙看看什么原因?

回答
編輯回答
愿如初

有沒(méi)有大神指教一下?十分感謝!謝謝啦!

2018年4月20日 11:47