Laravel+SPA+JTWAuthで認証ありの投稿アプリをつくる ~パート3~

# はじめに
サーバーサイドの処理はLaravelでクライアントサイドはSPAで認証、新規会員登録、記事の投稿を一括で作成しましたので、自分用のメモ含め紹介いたします。

# 前提
Laravel5.5
Vagrant環境
認証はJTWAuth使用
SPAはVue、Vue Router

前回のパート１、２の続き
パート1　https://qiita.com/ProgramingDai/items/403ee4fbc0971827f160
パート２　https://qiita.com/ProgramingDai/items/dd14e02b804be1ed5516

# 今回作るもの
新規会員登録をSPAで実装

# 手順レシピ
1.リソースファイル生成・編集

```console:リソースファイル生成
$ php artisan make:resource User
```
app/Http/Resoucesの中にUser.phpが生成

```php:app/Http/Resouces/User.php
namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class User extends Resource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'password' => $this->password,
            'date' => $this->created_at->format('Y-m-d H:i:s'),
        ];
    }
}
```

2.コントローラー生成・編集

```console:コントローラー生成
php artisan make:controller UserController
```

```php:app/Http/Controllers/UserController
namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;
use App\Http\Resources\User AS UserResource;

class UserController extends Controller
{
    // 一覧表示
    public function index() {
        return UserResource::collection(User::all());
    }

    // 保存
    public function store(Request $request) {
        $user = new User;
        $user->name = $request->input('name');
        $user->email = $request->input('email');
        // bcrypt関数でハッシュ化してくれる
        $user->password = bcrypt($request->input('password'));

        $user->save();
    }

    // １データ表示
    public function show(User $user) {
        return new UserResource($user);
    }

    // 更新
    public function update(Request $request, User $user) {
        $user->name = $request->input('name');
        $user->email = $request->input('email');
        // bcrypt関数でハッシュ化してくれる
        $user->password = bcrypt($request->input('password'));
        $user->save();
    }

    // 削除
    public function destroy(User $user) {
        $user->delete();
    }
}
```

３.ルーティング設定

```php:routes/api.php
// 中略
Route::resource('users', 'UserController');
```

4.router.jsの編集

```js:resources/asset/js/router.js
// 中略
import Register from './components/pages/Register' //　追加

// 中略
const routes = [
    { path: '/', component: Home, meta: { requiresAuth: true }  },
    { path: '/register', component: Register, name: 'register' }, // 追加
    { path: '/login', component: Login },
    { path: '/user', component: User, meta: { requiresAuth: true } },
    { path: '/list', component: List, meta: { requiresAuth: true }, name: 'list' },
    { path: '/create', component: Form, meta: { requiresAuth: true }, name: 'create' },
    { path: '/:id', component: Detail, meta: { requiresAuth: true }, name: 'detail' },
];

// 中略
```
Register.vueを追加するので、その設定。
「`path: '/register'`」でアクセスすると表示されるようにします。
App.vueにリンクを追加してください。
`<li><router-link to="/register">新規会員登録</router-link></li>`

5.Register.vueの作成

```html:resources/asset/js/components/pages/Register.vue
<template>
    <div class="container">
        <div v-if="saved" class="alert alert-primary" role="alert">
        保存しました
        </div>
        <form>
            <div class="form-group">
                <label for="UserName">ユーザー名</label>
                <input type="text" class="form-control" id="UserName" v-model="name">
            </div>
            <div class="form-group">
                <label for="UserEmail">メールアドレス</label>
                <input type="text" class="form-control" id="UserEmail" v-model="email">
            </div>
            <div class="form-group">
                <label for="UserPassword">パスワード</label>
                <input type="password" class="form-control" id="UserPassword" v-model="password">
            </div>
            <button type="submit" class="btn btn-primary" @click.prevent="create">新規会員登録</button>
        </form>
    </div>
</template>

<script>
export default {
    data: function() {
        return {
            saved: false,
            name: '',
            email: '',
            password: '',
        }
    },
    methods: {
        create : function() {
            axios.post('/api/users', {
                name: this.name,
                email: this.email,
                password: this.password,
            })
            .then((res) => {
                this.name = '';
                this.email = '';
                this.password = '';
                this.saved = true;
                console.log('created');
            });
        }
    }
}
</script>
```

以上で新規会員登録も簡易的ですがSPAで実装できました。
今は不備があったら、コンソール上でエラーが出ますが、
実際にバリデーションエラーを描画させることも、今後やっていきたいですね。

# 補足
js側を変更した場合は
`npm run dev`しないと更新されませんので、ご注意ください。