前提
この記事は @vue/cli を使用した内容となっております。
バージョン
"vue": "^2.5.17",
"vue-router": "^3.0.1",
"vuex": "^3.0.1"
ページ構成
- ホーム
- プロフィール
- ログイン
このうち、プロフィールはログイン認証が必要なページとします。
ソースファイル
上記ページ構成のファイルをそれぞれ用意します。
- src/views/Home.vue
- src/views/Profile.vue
- src/views/Login.vue
※上 2 つの中身は適当で大丈夫です。ログインページは後述します。
ルーター設定
src/router.js を編集します。
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import store from './store' // (1)
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/',
component: Home
},
{
path: '/profile',
component: () => import('./views/Profile.vue'),
meta: { requiresAuth: true } // (2)
},
{
path: '/login',
component: () => import('./views/Login.vue')
}
]
})
// (3)
router.beforeEach((to, from, next) => {
if (to.matched.some((record) => record.meta.requiresAuth)) {
if (!store.getters.loggedIn) {
next({
path: '/login',
query: {
redirect: to.fullPath,
message: true
}
})
} else {
next()
}
} else {
next()
}
})
export default router
(1) ログイン情報を参照するため store をインポートしておきます。
(2) プロフィールページはログイン認証が必要なため、 meta: { requiresAuth: true } を追加しておきます。
ここでの requiresAuth は適宜変更して大丈夫です。
(3) ページ遷移した際に、ログインしていない状態かつログイン認証が必要な場合は、ログインページに遷移するようにしています。
ログインページに遷移させる際、redirect: to.fullPath を与えて、ログイン完了後にもともと遷移しようとしていたページにリダイレクトできるようにしております。
message: true に関しては、強制的にログインページに飛ばされた時用にメッセージを表示させるフラグになります。
ストア設定
src/store.js を編集します。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
userId: ''
},
getters: {
loggedIn: (state) => {
return Boolean(state.userId.trim())
}
},
mutations: {
setUserId(state, userId) {
state.userId = userId
}
},
actions: {}
})
ログインした際のユーザ ID を保持しておくようにしています。
getters の loggedIn では、userId に何らかの値がセットされている場合に true を返すようにしています。
ルートページの設定
src/App.vue を編集します。
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/profile">Profile</router-link> |
<a @click="logout()" v-if="$store.getters.loggedIn">Logout</a>
<!-- (1) -->
<router-link
:to="'/login?redirect=' + $route.fullPath"
v-else-if="$route.path !== '/login'"
>Login</router-link
>
<!-- (2) -->
</div>
<div v-if="$route.query.message">ログイン認証が必要なページです。</div>
<!-- (3) -->
<router-view />
</div>
</template>
(1) ログアウト処理をするためのリンクです。
ログインしている状態の時にだけ表示するようにしています。
(2) ログインページに遷移するためのリンクです。
遷移先のパラメータに redirect を含めることで、ログイン処理後に元いたページにリダイレクトさせることができるようになります。
また、ログインしていない状態かつログインページ以外で表示するようにしています。
(3) 強制的にログインページに飛ばされた際に表示させるメッセージです。
<script>
export default {
methods: {
logout () {
this.$store.commit('setUserId', '')
if (this.$route.meta.requiresAuth) {
this.$router.push({
path: '/login',
query: { redirect: this.$route.fullPath }
})
}
}
}
}
</script>
ストアで保持しているユーザ ID を空にします。
また、ログインが必要なページでログアウトした際、強制的にログインページに飛ばすようにしています。
この時もやはりリダイレクトで戻って来られるようにパラメータを渡しています。
ログインページの設定
src/views/Login.vue を編集します。
<template>
<div class="about">
<h1>This is an login page</h1>
<input v-model="userId" />
<button @click="login()" :disabled="!userId">ログイン</button>
</div>
</template>
ユーザ ID 入力欄とログインボタンを設置しています。
ログインボタンは、ユーザ ID が未入力の場合は非活性にしています。
<script>
export default {
data () {
return {
userId: ''
}
},
methods: {
login () {
this.$store.commit('setUserId', this.userId) // (1)
this.$router.push(this.$route.query.redirect) // (2)
}
}
}
</script>
(1) 入力したユーザ ID でストアを更新しています。
(2) 元いたページにリダイレクトさせます。
コメント