Nuxt.jsで、型安全にrouterを扱うモジュール[Nuxt Typed Router]の使い方
はじめに
useRouterを使って、router.push()で、間違えて存在しないパスを指定したり、パス構成を忘れて、わざわざパス構成を確認してしまう。。
ということはありませんか?
今回は、そんなミスや手間を省くことができる、「Nuxt Typed Router」というモジュールを紹介します。
このモジュールは、型安全にrouterを使うことができるモジュールです。
今後も使えそうな、良さげなモジュールでした!
元々はpathpidaを使おうと思ったのですが、どうやらVue2/Nuxt2系対応のようで、Nuxt3ではうまくいかず。。こちらを見つけました。
公式はこちら↓
このモジュールを使って得られること
- パスを指定するとき、型補完が効く
- 存在しないパスを設定したら、エラーを出してくれる
例えば、こんな感じになります。
存在しないパスを指定すると、怒られます。
モジュールの仕組み
NuxtのuseRouter / useRoute / navigate / NuxtLinkなどに対して、アプリケーションのパスの構成に応じて型を自動生成してくれます。
例えば、Nuxt3アプリケーションのpagesフォルダの配下が、以下の状態の場合どうなるか説明しますね。
/pages
L news
L index.vue
L detail
L [id].vue
L about
L index.vue
自動生成後は、router.push()の引数で、
- /news
- /news/detail:id
- /about
以外のパスを指定すると、エラーが出るようになります。
実際に使ってみる
導入
インストール
npm install nuxt-typed-router
nuxt.config.tsにモジュール登録
export default defineNuxtConfig({
modules: [
'nuxt-typed-router',
]
})
型の自動生成
導入後、npm run dev・npm run buildなどをすると、pagesの構成を見て型を生成してくれます。
以下が出たら、型が生成されたということです。
router.pushを使ってみる
router.pushで、補完が効いてます。存在しないパスを設定すると、エラーが出ます。
※案件の内容になるので、補完部分隠してます。
route.paramsを使ってみる
routeはちょっとコツが要ります。
存在しないパスパラメーターにアクセスすると型エラーが出てしまうので、型ガードをする必要があります。
<script setup lang='ts'>
const route = useRoute();
console.log(route.params.foo);
// fooが存在しないパスもあるので、エラーが出る。
if (route.name === 'foo') {
console.log(route.params.foo) // これであれば、エラーがでない。
}
</script>
別の方法
useRouteの引数に、パス or 自動生成されたパス名を設定すると、設定したパス名のrouteになるので、型ガードの必要がありません。
<script setup lang='ts'>
const route = useRoute('admin-id'); // パス名を指定してuseRouteを使う
console.log(route.params.id) // adminにidというパラメーターがあるので、エラーが出ない。
</script>
コンポーネントを作る場合
UIライブラリのボタンコンポーネントに、toやhrefなどのpropsでリンク設定すること結構ありますよね。
Nuxt Typed Routerは、流石にUIライブラリのボタンコンポーネントのリンクのpropsの型を上書きしてくれないので、自作する必要があります。
結論から言うと、以下のような感じです。VuetifyのVBtnを例に挙げてます。
<template>
<VBtn :to="props.to">
<slot />
</VBtn>
</template>
<script setup lang="ts" generic="T extends RoutesNamesList, P extends string">
import type { RoutesNamesList, NuxtRoute } from '@typed-router';
interface Props {
to: NuxtRoute<T, P>;
}
const props = defineProps<Props>();
</script>
公式にやり方が書いてありました
URL: https://nuxt-typed-router.vercel.app/usage/typing-components
ポイントとしては、
- scriptタグに、genericで型引数を設定(propsのtoに入力されたの容によって、propsのtoの型が変わる)
- 一回const propsに受けてから、VBtnにtoを設定しないと、VBtnのtoのところで怒られる。(なぜこうなるかはわからん)
と言う感じです。
自動生成した型たちを使う
@typed-routerというエイリアスから、Nuxt Typed Routerが生成してくれた型をimportして使うことができます。
以下のような感じ
import type { RoutesNamesList, RoutesParamsRecord } from '@typed-router';
importできる型は以下に書いてあります。
ヘルパー関数で、存在するパスかどうかチェックする
helpers.path
import {helpers} from '@typed-router';
const route = helpers.path('/news') // 存在しないパスならエラーが出る
helpers.route
import {helpers} from '@typed-router';
const route = helpers.route({name: 'admin-id'}) // 存在しないパス名ならエラーが出る
参考: https://nuxt-typed-router.vercel.app/usage/helpers
終わりに
プロジェクト始めるタイミングで、こちらを入れると、型安全に画面遷移・パラメーター取得ができるようになって、ミスが減って良いと思います。
参考
Discussion