何度かやってるのに忘れるので備忘録がてらに。
結論: computedを使って取得
結論だけ読みたい人は以下読んでもらったら十分です。
// useRoute()を実行
const route = useRoute();
// パスパラメータの取得方法
const pathParams = computed(() => route.params.slug || 'default');
// クエリパラメータの取得方法
const queryParams = computed(() => route.query.key || 'default');
watchでも取得できますが、個人的にあまり好きくないのでここでは書きません。
何故この書き方でないと良くないのかは以下に記載します。
useRoute()を利用した取得方法(非リアクティブ更新)
Nuxt3でパスパラメータ/クエリパラメータを取得する場合はuseRoute()を使って取得します。
ドキュメント
// useRoute()を実行
const route = useRoute();
// パスパラメータの取得方法
const pathParams = route.params.slug;
// クエリパラメータの取得方法
const queryParams = route.query.key;
ですがこの方法ではNuxtLinkでパス/クエリパラメータが変更した際にページ内の値が変更されません。
<script lang="ts" setup>
// useRoute()を実行
const route = useRoute();
// パスパラメータ
const slug = route.params.slug;
</script>
<template>
<span>{{ slug }}</span>
<NuxtLink :to="`/pages/${slug}`">aaa</NuxtLink>
<NuxtLink :to="`/pages/${slug}`">bbb</NuxtLink>
</template>
このようなファイルがあったときに/pages/aaa にアクセスしてbbbのリンクをクリックしてもの中のslugは更新されません。
原因
原因はconst slug = route.params.slug;が非リアクティブのため、再読込されないためです。
Nuxtの性質上、NuxtLinkで遷移した際は現在描写されているコンポーネントが再利用されるため、setupで定義された非リアクティブ変数は基本最初に読み込まれたあとは再読込されずに最初に読み込んだ値を破棄するまで利用します。
これを回避するには以下の方法があります。
- computed(算出プロパティ)によるリアクティブ化
- watchを利用してパラメータの変更を監視
のどちらかを利用することでクエリパラメータが変更されたときに再度読み込んで最新の値を取得することができます。
解決法(computed)
さっきの例のファイルだとこんな感じになります。
<script lang="ts" setup>
// useRoute()を実行
const route = useRoute();
// パスパラメータ
const slug = computed(() => route.params.slug || 'default');
</script>
<template>
<span>{{ slug }}</span>
<NuxtLink :to="`/pages/${slug}`">aaa</NuxtLink>
<NuxtLink :to="`/pages/${slug}`">bbb</NuxtLink>
</template>
computedは中の値が変更されると動的に値を再計算してくれるので今回のようにroute.paramsが変更されると再評価してくれます。
computedはuseRouteとはかなり相性いいので、基本この書き方でいいと思います。
むしろwatchだと可読性が下がってしまう可能性がなくもないかなと思ってます。。
※ 注意点: computedは基本引数を利用しません。引数を利用するものは普通にfunctionかアロー関数を定義して利用しましょう。引数を利用した関数を監視したい場合はwatchを使いましょう。
最後に
最近ClineとClaude Code使い始めました。どっちも良き。ClineはOpen Router使ってるんですが、従量制課金じゃないのほんといい。前金制すごく良き。従量制課金でどえらいことになってる事例を何度かみてるので前金のほうがむしろ安心して使える。
1000円でもいいのでOpenRouter使うのはありだと思います。興味ある方はぜひ。