【Laravel+Vue.js】アプリ制作の記録⑧DB連携(会員登録/ログイン機能)

はじめに

現在Laravel+Vue.jsでのアプリ制作の記録です。

前回の記事で思わぬ挫折を味わいましたが、仕切り直して頑張ります。

この記事ですることは引き続き以下です。(かなり手探りで制作しています。)

Vue.jsでのDBへの追加・編集・削除。

一番シンプルに実装できそうな会員登録/ログイン機能でまずはDBへの追加に挑戦します。

アプリ制作するならマストで越えなければいけない壁。頑張ります。

※前回までの記録。

【Laravel+Vue.js】アプリ制作の記録①設計

【Laravel+Vue.js】アプリ制作の記録②プロジェクト作成

【Laravel+Vue.js】アプリ制作の記録③Vue Routerの実装

【Laravel+Vue.js】アプリ制作の記録④Vuexの実装

【Laravel+Vue.js】アプリ制作の記録⑤Vue.js側の作成

【Laravel+Vue.js】アプリ制作の記録⑥DBからのデータ取得

【Laravel+Vue.js】アプリ制作の記録⑦DB連携(会員登録/ログイン機能)

現状の確認と改修

と、本題に取り掛かる前に思ったことがいくつかあったのでまとめます。

・コントローラ構成見直し

・CardテーブルのAPI表示

・API取得データの表示場所

コントローラ構成見直し

現状ListingControllerの編集をほぼしていません。

追記したのはindexアクション。単純にviews/index.blade.phpを返すようにしただけ。

正直不要だし、APIディレクトリ下にコントローラを作るのであれば命名で被らないようにする手間もあるので一旦削除(厳密にはミュート)しました。

それに伴い、web.phpの編集。

<?php
Route::get('/',function(){
  return view('index');
});

非常にシンプルで理解のしやすい実装になりました。

CardテーブルのAPI表示

【Laravel+Vue.js】アプリ制作の記録⑥DBからのデータ取得でlistingsテーブルのデータは取得していました。
cardsテーブルもシードデータまで入れたのだから表示したいなと思ったので復習がてら実装。

①api.phpの編集

Route::group(['middleware' => ['api']], function () {
    Route::get('list', 'Api\ListController@index');
    Route::get('card', 'Api\CardController@index'); // add
  });

④Api/CardControllerの作成

php artisan make:controller Api/CardController

⑤CardControllerの編集

<?php

namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Card;

class CardController extends Controller
{
    public function index()
    {
      $cards = Card::orderby('id', 'desc')->get();
      return $cards;
    }
}

http://127.0.0.1:8000/api/cardへアクセス。

⑥Vue側でAPIを呼び出し

App.vueを編集

<template>
  <div>
    <header>
      <h1><router-link to="/">My Note</router-link></h1>
      <router-link to="Login">ログイン</router-link>
      <router-link to="Register">会員登録</router-link>
    </header>
    <main>
      <RouterView />
    </main>
    <footer>
      <h4>以下はapi/listで取得したデータです。</h4>
      <div v-for="(list, index) in listing" :key="index">
        <p>{{list.title}}</p>
      </div>
      <h4>以下はapi/cardで取得したデータです。</h4>
      <div v-for="(card, index) in card" :key="index">
        <p>{{card.title}} {{card.status}}</p>
      </div>
    </footer>
  </div>
</template>

<script>
export default {
  data() {
    return {
      listing :[],
      card :[]
    };
  },
  components: {
  },
  mounted() { 
    this.$http.get("/api/list").then(response => {
      this.listing = response.data;
    });
    this.$http.get("/api/card").then(response => {
      this.card = response.data;
    });
  },
}
</script>

http://127.0.0.1:8000/へアクセス。以下のように取得できていることがわかります。

API取得データの表示場所

注意
ここはかなり自分の学びの備忘録です。$emitの理解をされている方はスキップしてください。

APIで取得したデータをfooterタグ内に仮で入れて表示してました。

こちらをしっかりと適切なコンポーネントで表示されるように編集します。

Vue.js/Vuexを使ってTrello風アプリを作成しよう!

上記教材通りだと以下のような実装になっています。

リストデータ:Board.vueでStore/index.jsのリストデータを取り出し属性(v-bind)で渡す。List.vueでpropsで受け取る。

カードデータ:List.vueから渡されたカードデータを更にCard.vueでpropsで受け取る。

今回はAPIでデータ取得するので不要な部分もそぎ落としつつ編集していきます。

編集前に念のためここまでのソースコード

①子コンポーネントのList.vueでListデータを取得する

App.vueに記載していた非同期処理用のプロパティを諸々List.vueに記載。

表示されない。

原因は子コンポーネントで取得したデータを親コンポーネントに渡す記述をしていないからでした。

propsの逆パターンでこの場合、親側はカスタムイベント(v-on)、子側は$emitの引数で値を渡します。

ここにきて教材でVuexを使っている理由がわかりました。

子コンポーネントからデータを追加する場合は全てstoreにdispatchしていたからです。

確かに、Board.vue>List.vue>CardAdd.vueでCardAdd.vueからデータ追加しようと思ったら訳わからなくなるわ。

②Vue Router直下のコンポーネントで取得する

【Laravel x Vue.js】SPAクイズアプリケーションを作ってみよう!

こちらの教材を確認。

APIデータはVue Routerでインポートされているコンポーネントまでなら普通に取得できるっぽい。

Board.vueを編集(App.vueから切り取り&ペースト)

無事表示されました。

追記:リロードしなかったからかもしれません。後に表示されなくなりました。。。

③子コンポーネントをまとめる。

上記の工程を通じて、コンポーネントはまとめた方が現状のミニマム仕様だと良いと感じたので編集。

Board.vueを編集。また、Card.vue/CardAdd.vue/List.vue/ListAdd.vueを削除。

<template>
  <div>
    <p>All: no tasks</p>
    <p>list title</p>
    <p>card total: 0</p>
    <p>card title</p>
    <button @click="removeCardFromList">card delete</button>
    <button @click="removeList">list delete</button>
    <form @submit.prevent="addList">
      <input v-model="title" type="text" placeholder="Add new list">
      <button type="submit">リスト追加</button>
    </form>
    <form @submit.prevent="addCardToList">
      <input v-model="body" type="text" placeholder="Add new card"/>
      <button type="submit">カード追加</button>
    </form>    
  </div>
</template>

<script>
export default {
}
</script>

④データの描画方法の勉強。

これでApp.vueとBoard.vue(router.js)でシンプルな親子関係ができました。

App.vueで非同期通信でデータを取得、Board.vueでそのデータを受け取れるよう編集します。

と、そうしたいところですが、その前にデータの描画方法の基本を勉強します。(全然できなかったので。。。)

example.vue

表示

初めてちゃんと理解できた気がします。

⑤コンポーネント間のデータの受け渡し

App.vueからBoard.vueへのデータの受け渡しにチャレンジ。

App.vueの編集

Board.vueの編集

http://127.0.0.1:8000/へアクセス。

こんな感じになりました。

ここまで終えて、冷静にリスト内にリストデータに紐づくカードを表示させる必要性があることに気付きましたが、一旦ステイします。

要改善ポイント
Board.vueで実はsdisplay:noneしているタグがあります。なぜかこれを入れないとv-forが機能しなかったので入れました。原因がわからなかったのですが、分かり次第追記します。

DB登録(会員登録/ログイン機能) part2

Vue.jsとも少し仲良くなれてきたのでいよいよ挑戦です!

※前回の記事part1で編集したファイルは全て編集前の状態に戻しました。

今度は【Laravel x Vue.js】SPAクイズアプリケーションを作ってみよう!を参考に実装していきます。

会員登録機能の実装

※教材の7-3以降を参考に進めました。

VeeValidateのインストール

npm install --save-dev vee-validate

②Register.vueの編集

③router.jsでnameプロパティを教材に倣って追加する。

④web.phpの編集

教材ではviewsディレクトリにフォルダ/ファイルを作成していますが、僕はweb.phpのみで処理できるようにしてみました。(後で失敗するかも??)

以下を追記

Route::get('/login',function(){
  return view('index');
});
Route::get('/register',function(){
  return view('index');
});

※7-4VeeValidateは追記量が多くなると思い、一旦スキップしました。

⑤CSRFトークンの記載

headタグ内に追記

<meta name="csrf-token" content="{{ csrf_token() }}">

Register.vueの編集

web.phpの編集

Route::post('/register', 'Auth\RegisterController@register');

RegisterController.phpの編集

protected $redirectTo = '/';

Middleware\RedirectIfAuthenticated.phpを編集

return redirect('/');

http://127.0.0.1:8000/registerで登録。

DBに反映されませんでした。

⑥やり直し

ところどころ端折ったせいかもしれません。

ってことで1から確認してみました。

web.phpの編集(加えてauth/register/index.blade.php※appをextend)

Route::get('/register', function () {
  return view('auth.register.index');
});

※原因はこれではなかったです!

Register.vueの編集

メソッドを追記しそびれていました。orz

  methods: {
    async register() {
      document.querySelector("#register").submit();
    }
  }

無事、登録が確認できました。

歓喜です!!

気づき
何回か試してわかったのですが、ログイン後はログアウトしない限り、会員登録の追加ができないです。

おわりに

認証関連はそもそもLaravelで既にコントローラなど準備されているものもあり、逆に実装の難しさを感じました。

とはいえ、Vue.js側からのDB追加を初めてすることができたので非常にうれしいです。

次はログイン・ログアウト機能に挑戦したいと思います。

ここまでのソースコード

※今回初めてGitHubを使っているけど、試しにブランチを追加してみたらブラックボックス化しました。。。

※そのうち訳わからずに操作してリンク切れとかしちゃいそう。笑

今回の気付き

①v-forを記載してコンポーネントを使用するとデータなかった場合なにも描画されなくなる。

②Vue Routerをハッシュモードで利用するとリロードしても読み込まれる。<a>タグでもhrefに#を付ければSPA遷移できる。
今までよくわからずにhistoryモードで利用していたけど、理解した上で使うのであればURLは美しくないけどハッシュモードも良いのではないかと感じた。

③.vueファイルの場合、dataはreturnの書き方で記載する。(.jsで書く際と異なる。)

④現状Vue Routerで遷移したURL(頭文字が大文字のバターン)だとリロードできない。

参考

このアプリは数々のチュートリアル・教材を参考に制作しています。

参考にさせていただいた教材は以下でご紹介させていただきます。

参考教材

Vue.js/Vuexを使ってTrello風アプリを作成しよう!

【Laravel x Vue.js】SPAクイズアプリケーションを作ってみよう!

Laravel(+Vue.js)でSNS風Webサービスを作ろう!

trello風todoタスク管理アプリを作成しよう!

Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう

入門Laravelチュートリアル (2) ToDoアプリケーションの設計

公式ドキュメント(英文)

 

公式ドキュメント

その他参考(Qiitaなど)

[Vue.js]dataオプションにオブジェクトや配列を設定してみる

コメントを残す