Vue 3 のエコシステムは 2021 年に徐々に成熟し、Vue Router 4 も安定版の段階に入った。年初に、中規模の管理画面システムの Vue Router 3 → 4 への移行を主導し、いくつものつまずきを経験したので、核心的な変化と移行の戦略をまとめておく。
ルート定義方法の変更
Vue Router 4 で最も直感的な変化は、インスタンスを作る API がコンストラクタ呼び出しから関数呼び出しになったことだ:
javascript
// Vue Router 3
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [...]
})
// Vue Router 4
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [...]
})
mode: 'history' が history 引数に置き換わる点に注意し、createWebHistory()、createWebHashHistory()、createMemoryHistory() のいずれかを明示的に呼ぶ必要がある。
ルートガードの調整
beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave のコンポジション API での書き方が変化している:
javascript
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
export default {
setup() {
// 替代 beforeRouteLeave
onBeforeRouteLeave((to, from) => {
if (hasUnsavedChanges()) {
return window.confirm('确定离开?未保存的数据将丢失')
}
})
// 替代 beforeRouteUpdate
onBeforeRouteUpdate((to, from) => {
if (to.params.id !== from.params.id) {
fetchUserData(to.params.id)
}
})
}
}
よくある落とし穴
1. * ワイルドカードルートはサポートされなくなった
Vue Router 4 は * ワイルドカードを削除し、代わりに /:pathMatch(.*)* を使う:
javascript
// Vue Router 3
{ path: '*', component: NotFound }
// Vue Router 4
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound }
// 或者多级嵌套:
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound }
2. $router 和 $route 类型变化
TypeScript プロジェクトでは、型安全なインスタンスを得るために useRouter() と useRoute() を使う:
typescript
import { useRouter, useRoute } from 'vue-router'
export default {
setup() {
const router = useRouter()
const route = useRoute()
// route.params 有正确的类型推断
console.log(route.params.id) // string | string[]
}
}
3. 移除了 router.match
router.resolve() で代用する:
javascript
// Vue Router 3
const route = router.match('/path')
// Vue Router 4
const resolved = router.resolve('/path')
移行戦略
我々が採用したのは段階的な移行だ:
- まず Vue Router パッケージをアップグレードし、ビジネスコードは変更せず、互換レイヤーを使って動かす
- ファイルごとに API を置き換え、ルート定義とガードを優先的に処理する
- 最後に TypeScript の型の問題をまとめて処理する
- 動的ルートとネストしたルートの場面を十分にテストする
移行全体のプロセスには約 2 週間かかり、主な時間は型の修正と境界ケースのテストに費やした。
まとめ
- Vue Router 4 の API 設計はより関数指向になり、Vue 3 のコンポジション API のスタイルと一致している
- ワイルドカードルートやルートガードの書き方の変化が、主な breaking change だ
- TypeScript のサポートが顕著に強化され、
useRouter/useRouteが推奨される手段だ - 段階的な移行戦略はリスクを効果的に下げられる
