この記事について
Nuxt の middleware や plugin でリダイレクトするのに
redirect('hogehoge');
のような書き方をしていたら、動作が想定外で困った&解決した話です。
困ったこと
router.push()
では route.name が変わる
こんなコードがあったとして
pages/mypage.vue
export default Vue.extend({
created() {
this.$router.push('/login');
}
});
pages/login.vue
export default Vue.extend({
created() {
console.log(this.$route.name);
// "login"
}
});
ブラウザから mypage
を呼び出してリダイレクトされた場合でも、 route.name
は login
になっています。
Nuxt の redirect
を使うと route.name が変わらない
middleware/redirectLogin.vue
export default function({ redirect }) {
// 〜ログイン済チェクとか〜
redirect('/login');
}
login.vue
export default Vue.extend({
created() {
console.log(this.$route.name);
// "mypage"
}
});
ブラウザで見る限りは login
にリダイレクトされているけれど、 route.name
は最初にアクセスしようとした mypage
のまま・・・
解決方法
redirect
を使って route.name を変える方法
これだと、 middleware や plugin で route.name
を参照している場合、リダイレクト後に想定しない挙動が起きてしまうことがあります。
middleware/redirectLogin.vue
export default function({ route, redirect }) {
// login ページに来ていたらチェックしない
if (route.name === 'login') {
return;
}
// ブラウザから見たら login に来ているけど、 route.name が mypage のままなので通過してしまう
// 〜ログイン済チェクとか〜
redirect({ name: 'login' });
}
困ったな〜と思っていたら、ちゃんと解決方法がありました🎉
https://github.com/nuxt/nuxt.js/issues/2421
middleware/redirectLogin.vue
export default function({ redirect }) {
// 〜ログイン済チェクとか〜
redirect({ name: 'login' });
}
login.vue
export default Vue.extend({
created() {
console.log(this.$route.name);
// "login"
}
});
コードを見ると、以下のように router.resolve
してくれていました。
これで安心!
utils.js
if (pathType === 'object') {
path = app.router.resolve(path).href
}