概要
- ルート定義が複数存在し、ユーザを切り替えた際にルート定義を入れ替えたい場合がある。(例:ログインユーザの権限に応じたルートを設定する)
- にもかかわらず、vue-router(v4)には、ルートを一括で入れ替える仕組みが存在しない。
- 以前のバージョンでは以下の方法で入れ替えができたようだが、現在(v4以降)では、機能しなくなっていた。
// 変更するルート定義
const createRouter = () => new Router({
...
routes: [...]
})
export function resetRouter () {
const newRouter = createRouter()
// matcherを入れ替えることで、ルート定義の洗い替えができた。
// →v4以降は機能しない!!
router.matcher = newRouter.matcher
}
※以下の引用
対応方法
- 1件づつ
removeRoute
でルートを消して、1件づつaddRouter
で追加する。 - 愚直だが、現状はこの方法しかなさそう。(
router
自体を入れ替える等しても動的にルートは変更できなかった)
// 変更するルート定義
const createRouter = () => new Router({
...
routes: [...]
})
export function resetRouter() {
// getRoutersで定義済みのルートを全て取得し、
// nameをキーにルートを1件づつ全て削除する。
router.getRoutes().forEach((route) => {
router.removeRoute(route.name)
})
const newRouter = createRouter()
// 変更後のルート情報を1件づつ追加する
newRouter.getRoutes().forEach((route) => router.addRoute(route))
}
補足 - ルートのname属性は必須(Symbolで定義)
-
removeRoute
は、name
をキーに削除するため、全てのルートにname
属性が必要となる -
name
を使用していないルートに関しては新たに設定が必要となる。影響がないよう、一意性を担保できるSymbol
で定義すると良い。
export const sampleRoutes: RouteRecordRaw[] = [
{
path: '/login',
// Symbolでnameを追加
name: Symbol('login'),
component: () => import(/* webpackChunkName: "login" */ '@/views/login/index.vue'),
meta: {...}
},
...
]
終わりに
-
matcher
のハックが使えなくなったので、1件づつの入れ替えをしたが、name
属性を設定していないルートがあったので、消せなくて困った。- 幸いSymbol属性が使えたので影響は少なかったが、後からの設定は面倒だったので、
name
属性は必須にしてもいいのではないか。
- 幸いSymbol属性が使えたので影響は少なかったが、後からの設定は面倒だったので、
- または、ルート定義の洗い替えはあると思うので、一括で消せるAPIが公式から提供されてほしい。