Vue Router で直アクセスを禁止する
Vue Router における直アクセスの判定について、ほどほどに使う割には記事として残っているのを見かけなかったので、記事にしてみます。
フォームの完了ページや診断の結果ページなど、他のページからページ遷移するけど直アクセスはさせたくない場合に使用できます。
直アクセスの条件
Vue Router で直アクセスするということは、ページ遷移元のページがないということです。
そういった遷移を判定するのに使えるのが START_LOCATION
です。
from
が START_LOCATION
と等しい場合に直アクセスとだとみなすことができます。
ユースケース
/hoge
は直アクセス可能で、 /fuga
は直アクセスさせたくない(Vue Router を使用して他のページからの遷移のみ許可したい)とします。
ベースとなるルート定義は下記のようになります。
(name
や component
など、今回の説明に不要な設定は省略しています。)
const routes = [
{
path: '/hoge',
},
{
path: '/fuga',
},
]
export default routes
そのルートにアクセスする前に何らかの処理を行いたい場合は beforeEnter
を使用します。
今回は /fuga
にアクセスする前に、beforeEnter
の中で from
が START_LOCATION
と等しいかを判定します。
等しかった場合、つまり /fuga
へ直アクセスされた場合は /hoge
へリダイレクトします。
import { START_LOCATION } from 'vue-router'
const routes = [
{
path: '/hoge',
},
{
path: '/fuga',
beforeEnter: (to, from) => {
if (from === START_LOCATION) { // 直アクセスだった場合
return '/hoge' // '/hoge' へリダイレクトする
}
},
},
]
export default routes
直アクセスを禁止したいページが複数ある場合、何度も同じ処理を書くのは面倒です。
なので直アクセス禁止の部分を関数に切り出した方が取り回しがしやすいです。
下記は直アクセス禁止の処理を denyDirectAccess
という関数へ切り出し、ルートに /piyo
と /hogera
も追加し、その両方とも直アクセスを禁止にした例です。
import { START_LOCATION } from 'vue-router'
/** 直アクセスを禁止する */
function denyDirectAccess(to, from) {
if (from === START_LOCATION) { // 直アクセスだった場合
return '/hoge' // '/hoge' へリダイレクトする
}
}
const routes = [
{
path: '/hoge',
},
{
path: '/fuga',
beforeEnter: denyDirectAccess,
},
{
path: '/piyo',
beforeEnter: denyDirectAccess,
},
{
path: '/hogera',
beforeEnter: denyDirectAccess,
},
]
export default routes
関数化することのもう1つのメリットは、ルートへのアクセス前、つまり beforeEnter
の中で他の処理も行いたい場合にも、見通しが良くなります。
beforeEnter
に渡す関数を配列にすることで、複数の処理を行うことができます。
下記は /fuga
にアクセスした際に、直アクセス判定の他にも別の処理を行う例です。
import { START_LOCATION } from 'vue-router'
/** 直アクセスを禁止する */
function denyDirectAccess(to, from) {
if (from === START_LOCATION) { // 直アクセスだった場合
return '/hoge' // '/hoge' へリダイレクトする
}
}
/** 別の処理1 */
function otherProcess1(to, from) {
// 別の処理1
}
/** 別の処理2 */
function otherProcess2(to, from) {
// 別の処理2
}
const routes = [
{
path: '/hoge',
},
{
path: '/fuga',
beforeEnter: [denyDirectAccess, otherProcess1, otherProcess2],
},
]
export default routes
Discussion