開発Divのeciです。
今年はVue Fes Japanが秋にあることですし、周りがみんな「vue,vue」言い始めたので、Vue.jsを触ってみました。
調べていくとNuxt.jsというフレームワークがよさげですので、今回はこれのチュートリアルを元に拡張していこうと思います。
Nuxt.jsにはスターターテンプレートが用意されていますが、今回は「スクラッチから始める」の方を参考にしていきます。
ただ、このままですと味気ないですので、ログイン認証まで作っていきます。
では、行きましょう!
まずは、Helloページ表示まで
ディレクトリを作成
$ mkdir hello $ cd hello
package.jsonの作成
helloディレクトリ直下にpackage.jsonを作ります。
{ "name": "hello", "scripts": { "dev": "nuxt" } }
Nuxt.jsのインストール
npm install --save nuxt
最初のページを作成
$ mkdir pages $ cd pages
pagesディレクトリに、index.vueを作ります。
<template> <div class="container"> <h1>hello</h1> </div> </template>
起動
$ npm run dev
ブラウザで「localhost:3000」に行くと、「hello」と表示されましたか?
ログイン認証の実装
ここからいよいよログイン認証を作って行きます。
ちなみに、ここを参考にしています。
やること
- ログインページの作成
- ストアの用意
- ミドルウェアの実装
- nuxt.config.jsの用意
- hello.vueの作成(indexページだけだと味気ないので...)
- index.vueの修正
ログインページの作成
pagesディレクトリにlogin.vueを作ります。
<template> <div class="container"> <form @submit.prevent="login"> <p class="error" v-if="formError">{{ formError }}</p> <p>name:<input type="text" v-model="formUsername" name="username" /></p> <p>password:<input type="text" v-model="formPassword" name="password" /></p> <button type="submit">ログイン</button> </form> </div> </template> <script> export default { data() { return { formError: null, formUsername: "demo", formPassword: "pass", } }, methods: { async login() { try { await this.$store.dispatch('login', { username: this.formUsername, password: this.formPassword }) this.$router.push('/') } catch(e) { this.formError = e.message } }, } } </script>
ストアの用意
Vueでグローバルなステートを管理するために、Vuexというライブラリが用意されています。
$ mkdir store $ cd store
storeディレクトリにindex.jsを作成します。
export const state = () => ({ authUser: null, }) export const mutations = { SET_USER: function (state, data) { if (data) { state.authUser = data } else { state.authUser = null } } } export const actions = { async login({ commit }, { username, password }) { try { //const res = await axios.post('/login', { username, password }) 本当は、たぶんこんな感じ if (username != "demo" || password != "pass") { throw new Error("エラーですよ") } commit('SET_USER', username) } catch (error) { throw error } }, async logout({ commit }) { try { commit('SET_USER', null) } catch(error) { throw error } } }
ミドルウェアの設定
Nuxt.jsでは、あるページがレンダリングされる前に実行される関数を、middlewareという仕組みを使って実装できますので、 これを使って各ページの認証を行います。
$ mkdir middleware $ cd middleware
middlewareディレクトリにauth.jsを作ります。
middleware/auth.js
export default function ({ route, store, redirect }) {
if (!store.state.authUser && route.path != "/login") {
return redirect('/login')
}
}
nuxt.config.jsの用意
helloディレクトリ直下にnuxt.config.jsを用意します。
module.exports = { head: { title: 'Hello', meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', content: 'Hello' } ] }, //mode: 'spa', router: { middleware: 'auth' }, }
hello.vueの作成
pagesディレクトリにhello.vueを作成します。
<template> <div class="container"> <h1>こんにちは</h1> <nuxt-link to="/">Topページへ</nuxt-link> </div> </template>
index.vueの修正
helloページへのリンクおよび、ログアウトボタンを追加します。
pages/index.vue
<template>
<div class="container">
<h1>スクラッチから始めるNuxtログイン</h1>
<button v-on:click="logout">ログアウト</button>
<nuxt-link to="/hello">helloページへ</nuxt-link>
</div>
</template>
<script>
export default {
data() {
return {
formError: null,
formUsername: "demo",
formPassword: "pass",
}
},
methods: {
async logout() {
try {
this.$store.dispatch('logout').then(() => {
this.$router.push('/login')
})
} catch (e) {
this.formError = e.message
}
}
}
}
</script>
起動および動作確認
$ npm run dev
ログアウトした状態で「/hello」にアクセスしても、無事「/login」に戻ってきますね。
まとめ
htmlとjs合わせて100行ちょっとでログイン認証の雛形が出来てしまいました。
また、学習コストもかなり低いと思いました。
まだ始めたばかりですので、よりよい書き方を追求していきたいと思います。