VueRouterでパスの一部として定義されていないParamsを渡すと、値が消失する
VueRouter でパスの一部として定義されていない Params を渡すと、値が消失する
事象
Vue Router でパスの一部として定義されていない params を渡そうとしたとき、
以下の警告が発生して、受け渡した Params の値がundefined
になっていました。
エラーが発生したコード
受渡元
router.push({ name: "somewhere", params: { hoge: "i am params" } });
router.ts
{
path: "/somewhere/",
name: "somewhere",
component: somewhere,
props: (route: RouteLocationNormalized) => ({ id: route.params.hoge }),
},
受渡先
import { useRoute } from "vue-router";
const route = useRoute();
const q = route.params.id;
エラー内容
[Vue Router warn]: Discarded invalid param(s) "q" when navigating. See https://github.com/vuejs/router/blob/main/packages/router/CHANGELOG.md#414-2022-08-22 for more details.
エラー要約
結論
Vue Router v4.1.4 から[パスの一部として定義されていないパラメータを渡す]ことは廃止になりました。
代替手段としては以下を使ってくださいとのこと。
- ストアにデータを保持する
- ルートのパスにデータを定義するか、クエリパラメータとして渡す
- History API state にデータを保存する
- ナビゲーションガードのなかで to.meta プロパティにデータを渡す
背景
参考文献内容
This change will break your app. This behavior has worked in some scenarios but has been advised against for years as it's an anti-pattern in routing for many reasons, one of them being reloading the page lose the params.
要約
この変更によってアプリが壊れる可能性があります。この振る舞いは一部のシナリオで機能していましたが、ルーティングにおいて反パターンとされており、ページの再読み込みによりパラメータが失われるため、多くの理由から長年にわたって推奨されていませんでした。
代替手段
ストアにデータを保持させる
Pinia などの状態管理ライブラリを使いましょう。
ルートのパスにデータを定義するか、クエリパラメータとして渡す
router.ts を以下のように変える
router.ts
{
path: "/somewhere/:id",
name: "somewhere",
component: somewhere,
props: (route: RouteLocationNormalized) => ({ id: route.params.hoge }),
},
History API state にデータを保存する
文献によると、以下のように書けば渡せる(動作未確認)
state
to save it to the History API state
<router-link :to="{ name: 'somewhere', state: { myData } }">...</router-link>
<button
@click="$router.push({ name: 'somewhere', state: { myData } })"
>...</button>
ナビゲーションガードのなかで to.meta プロパティにデータを渡す
参考文献の以下コードのようにする
router.beforeEach(async (to) => {
if (to.meta.shouldFetch) {
// name `data` whatever you want
to.meta.data = await fetchSomething();
}
});
参考文献
Discussion