

Vue Router 3のthis.$route.queryでクエリパラメータは取れるけど、lazy loadingだと取れないことがあるらしい
この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。
Vue.js 2 + Vue Router 3でクエリパラメータを取るなら this.$route.query を見ればいい。ただしルートをlazy loadingしている構成だと、createdフックの時点でqueryが空になることがあるらしい。挙動が怪しいと思ったらまずここを疑う。
基本の取り方
Vue Routerでルートを定義しておけば、コンポーネント側は this.$route.query にアクセスするだけでいい。
import Vue from 'vue';import Router from 'vue-router';import ExamplePage from './components/ExamplePage.vue';
Vue.use(Router);
export default new Router({ routes: [ { path: '/example', name: 'ExamplePage', component: ExamplePage, }, ],});コンポーネント側はこう。
<template> <div> <p>ID: {{ $route.query.id }}</p> </div></template>
<script>export default { name: 'ExamplePage', mounted() { console.log(this.$route.query.id); },};</script>params と混同しがちだけど、?id=1 みたいなクエリ文字列は query、/users/:id みたいな動的セグメントは params。別物として覚えておく。
lazy loadingだと危ういケース
ルートをlazy loadingしている場合(component: () => import('./ExamplePage.vue') みたいなやつ)、App.vue の created フックの時点で this.$route.query を見ると空になるという報告がVue RouterのGitHub issueに上がっている。
再現条件として挙げられていたのは以下。
- vue-cliでプロジェクトを作ってvue-routerを導入
App.vueのcreatedでthis.$route.queryをログ出力- lazy loadedなルートに直接アクセス(例:
/#/about?tiers=xxx)
このケースだとqueryが取れず、逆にトップページ(/#/?tiers=xxx)だと取れる、という切り分けがされていた。実機未確認だけど、lazy loadingを使っていて App.vue レベルでqueryに依存した初期化処理を書いている場合は要注意かもしれない。個別コンポーネントの mounted や created で見る分には基本問題にならないはず。
まとめると
- 通常のコンポーネント内でクエリを取るだけなら
this.$route.queryで十分 App.vueなどのルート直下でlazy loadedなルートのqueryに依存する処理を書くなら、タイミングに注意した方がいい