Vue CLI × Laravel × VuetifyでCSSいらずの爆速開発でTodoリストを作る part4

#前回のパート
前回は、全ページで使用するヘッダーの作成と会員登録の処理の実装を行いました
前回のパートはこちら→[Vue CLI × Laravel × VuetifyでCSSいらずの爆速開発でTodoリストを作る part3](https://qiita.com/Kyu-Taro/items/ea7452abfdf473e16cd5)
今回は、前回実装し登録をした内容を利用してログイン機能の実装をしていこうと思います

#ログインフォームの実装(Vue側)
まずはログインフォームのview側の実装をしていきます
`client/components`に`Login.vue`を作成して下記を追加してください

```Login.vue
<template>
    <div>
        <Header />
        <div class="main-container">
            <v-form v-model="valid">
                <v-text-field v-model="form.email" :rules="emailRules" label="E-mail" required></v-text-field>
                <v-text-field v-model="form.password" :rules="passwordRules" label="Password" required type="password"></v-text-field>
                <v-btn small>submit</v-btn>
            </v-form>
        </div>
    </div>
</template>

<script>
    import Header from './Header';

    export default {
        components: {
            Header
        },
        metaInfo: {
            title: 'ログイン',
            htmlAttrs: {
                lang: 'ja'
            }
        },
        created () {
            const user = this.$store.getters['auth/user'];
            if (user !== null) {
                this.$router.push('/todo');
            }
        },
        data () {
            return {
                form: {
                    email: '',
                    password: '',
                },
                emailRules: [
                    v => !!v || 'E-mailを入力してください',
                    v => /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(v) || 'E-mailを正しく入力してください'
                ],
                passwordRules: [
                    v => !!v || 'パスワードを入力してください'
                ]
            }
        }
    }
</script>

<style>
    .main-container {
        width: 500px;
        margin: auto;
    }
</style>

```
前回の`Register.vue`と内容はほとんど同じなので
特に説明は必要ないかと思いますので、割愛します
説明が必要な方は、前回のパートに戻って確認してみてください

ではここにmethodを追加していきます

```Register.vue
<template>
    <div>
        <Header />
        <div class="main-container">
            <v-form v-model="valid">
                <v-text-field v-model="form.email" :rules="emailRules" label="E-mail" required></v-text-field>
                <v-text-field v-model="form.password" :rules="passwordRules" label="Password" required type="password"></v-text-field>
                <v-btn small @click="login">submit</v-btn>    //追加
            </v-form>
        </div>
    </div>
</template>

<script>
    import Header from './Header';

    export default {
        components: {
            Header
        },
        metaInfo: {
            title: 'ログイン',
            htmlAttrs: {
                lang: 'ja'
            }
        },
        created () {
            const user = this.$store.getters['auth/user'];
            if (user !== null) {
                this.$router.push('/todo');
            }
        },
        data () {
            return {
                form: {
                    email: '',
                    password: '',
                },
                emailRules: [
                    v => !!v || 'E-mailを入力してください',
                    v => /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(v) || 'E-mailを正しく入力してください'
                ],
                passwordRules: [
                    v => !!v || 'パスワードを入力してください'
                ]
            }
        },
        methods: {    //追加
            async login() {
                await this.$store.dispatch('auth/login', this.form);
                this.$router.push('/todo');
            }
        }
    }
</script>

<style>
    .main-container {
        width: 500px;
        margin: auto;
    }
</style>
```
ログイン時のmethodを追加しました
内容は、`auth.js`の`login`アクションにフォームに入力された内容を渡しdipatchしています
その処理が終われば、`/todo`のTodoページに遷移する様に設定してます

では次に、`auth.js`の`login`アクションを定義していきます
'auth.js`に下記を追加してください

```auth.js
import axios from 'axios';

const state = {
    user: null
}

const getters = {
    user: state => state.user
}

const mutations = {
    setUser (state, user) {
        state.user = user;
    }
}

const actions = {
    async register({ commit }, data) {
        const response = await axios.post('/api/register', data)
        commit('setUser', response.data);
    },

    async searchUser({ commit }) {
        const response = await axios.get('/api/user');
        const user = response.data ? response.data : null;
        commit('setUser', user);
    },

    async login({ commit }, data) {    //追加
        const response = await axios.post('/api/login', data);
        commit('setUser', response.data);
    }
}

export default {
    namespaced: true,
    state,
    getters,
    mutations,
    actions
}
```

今回追加したアクションはLaravelで定義した、`/login`のルートに対して入力されたデータをPOSTし
その、情報を変数responseに格納しています
そして、その値を`setUser`mutationに対してcommitしstateのuserの値をセットしています
registerの時と同じ流れになります

次に、Laravel側の実装をしていきます

#Laravel側の実装
Vue側での`auth.js`でPOSTしていた`/login`をルートに定義していきます
`api.php`に下記を追加してください

```api.php
Route::post('/register', 'Auth\RegisterController@register')->name('register');
Route::post('/login', 'Auth\LoginController@login')->name('login');    //追加
Route::get('/user', function(){
    return Auth::user();
});
```
これで`auth.js`の`login`アクションからaxiosでリクエストを投げられる様になりました

そして、part3で下記の記述を`LoginController.php`に追加してますのでこれでLaravel側での実装は完了です

```LoginController.php
    protected function authenticated(Request $request, $user)    //追加
    {
        return $user;
    }
```

上記までの記述で一通りログイン機能の実装が終わりました
ただ遷移する画面の`/todo`をまだ用意していないので正常に画面が遷移することができないので
ここで、`Todo.vue`コンポーネントを追加しておきましょう
`client/components`に`Todo.vue`ファイルを新規で作成してください
中身はこの様にしておいてください

```Todo.vue
<template></template>

<script></script>

<style></style>
```

次に`router.js`にコンポーネントを登録しておきます
`router.js`に下記を追加してください

```router.js
import Vue from 'vue';
import Router from 'vue-router';
import Login from '../components/Login';
import Register from '../components/Register';
import Todo from '../components/Todo';    //追加

Vue.use(Router);

export default new Router({
    mode: 'history',
    routes: [
        {
            path: '/login',
            component: Login
        },
        {
            path: '/signup',
            component: Register
        },
        {
            path: '/todo',    //追加
            component: Todo
        }
    ]
})
```

ここまでできたらログインを試してみてください
正常であれば、ログイン後`/todo`に遷移し真っ白な画面が表示されるかと思います

#終わりに
今回はログイン機能の実装を行いました
それに加えて、`/todo`ページの用意も行いました

次回は、ログアウト機能を実装したいと思います
次回のログアウト機能が終われば認証周りの実装は終わりですので、Todoを作っていく実装に入っていきます

次回のパートはこちら→[Vue CLI × Laravel × VuetifyでCSSいらずの爆速開発でTodoリストを作る part5](https://qiita.com/Kyu-Taro/items/693b9defdf66be3a5cb7)