Laravelとvueの連携!データベース内の一覧を表示する方法

さてさて、Laravelの生産性が高いことはこのブログでよく言ってるんですけど、最近の開発でもうひとつ生産性を上げてくれるものがあって、それが「vue.js」です。

vue.jsは「react」や「angular」のように、データ更新するとリアルタイムでHTMLを書き換えてくれるJavaScriptパッケージで、「表示部分だけ」に特化しているので、他のパッケージよりもシンプルなのが特徴です。

ということで、今回はLaravelとVueを連携させるコンテンツを作ってみたいと思います。

コンテンツの中身

実装するのは、

  • DBのデータをjsonで表示
  • Ajaxでjsonデータをとってくる
  • Vueで一覧を表示

の3つです。
では、実際のコードを見ていきましょう!

テストデータを作る

まずはデータベースにテスト用のデータを作成します。
今回は、comediansというテーブルを作ってお笑い芸人の名前をテストデータとして使いたいと思います。

まずは、マイグレーションとモデルを作成しましょう。
次のコマンド一発で完了します。

php artisan make:model Comedian -m

-m」をつけると自動でマイグレーションも作成してくれて便利ですね。

そして、「/database/migrations」に作成されたマイグレーションに名前フィールドを追加します。

Schema::create('comedians', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->timestamps();
});

変更が完了したら、マイグレーションを実行。

php artisan migrate

はい。これで、comediansテーブルが出来上がりました。

では、ここにSeederを使ってお笑い芸人さんのデータを入れていきましょう。

php artisan make:seeder ComediansTableSeeder

「/database/seeds」にファイルができているので、これを開いて以下のようにデータを追加するコードを書きます。

public function run()
{
    $comedian_names = [
        'ビートたけし',
        'タモリ',
        '明石家さんま',
        'ダウンタウン',
        'ナインティナイン',
        'ロンドンブーツ1号2号',
    ];

    foreach ($comedian_names as $comedian_name) {

        \App\Comedian::create([
            'name' => $comedian_name
        ]);

    }
}

コードが書き終わったら、このSeederを呼び出せるように「/database/seeds/DatabaseSeeder.php」に登録します。

public function run()
{
     $this->call(ComediansTableSeeder::class);
}

これで準備は完了です。次のコマンドを使ってテストデータを追加してみましょう。

php artisan db:seed

はい。これで、テストデータの準備も完了です!

データをjsonで表示する

Ajaxでアクセスするためのjsonを作成します。
まずはコマンドでコントローラーを作成しましょう。

php artisan make:controller Ajax\\ComedianController

そして、作成したコントローラーにjson用メソッドを追加します。

<?php

namespace App\Http\Controllers\Ajax;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class ComedianController extends Controller
{
    public function index() {

        return \App\Comedian::all();  // ←自動でjsonにしてくれます

    }
}

※ちなみに、Laravelのモデルデータ(コレクション)はreturnすると自動でjsonに変換してくれます。

「routes/web.php」にページ登録してページにアクセスしてみましょう。

Route::get('ajax/comedian', 'Ajax\ComedianController@index');

はい。jsonが表示されました。

Ajaxでデータを取得する

では、ここからメインページの作成にはいります。
まずは、やはりコントローラーが必要なので、以下のコマンドで作成しましょう。

php artisan make:controller ComedianController

作成したら、中身にメソッドとビューを設定します。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ComedianController extends Controller
{
    public function index() {

        return view('comedian');

    }
}

ビューの中身は(今の所は)こんなカンジです。

<html>
    <body>
        <div id="app">
            <table></table>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
        <script>

            new Vue({
                el: '#app'
            });

        </script>
    </body>
</html>

Routeにページ登録します。

Route::get('comedian', 'ComedianController@index');

では、このページにアクセスしたらすぐjsonデータを取得できるようにmounted()にコードを追加しましょう。

new Vue({
    el: '#app',
    mounted() {
        var url = '/ajax/comedian';
        axios.get(url).then(function(response){
            var comedians = response.data;
            console.log(comedians);
        });
    }
});

【追記:2019.05.14】 訪問ユーザーさんにご指摘をいただきましてコード内の「axois」というを訂正させていただきました。正しくは「axios」でした。わざわざご連絡いただいてありがとうございます😊✨

Google chromeのコンソールで見てみるとうまくAjaxでデータ取得できてるようですね。

では、取得したデータをVue内の変数に格納してあげましょう。

new Vue({
    el: '#app',
    data: {
        comedians: {}
    },
    mounted() {
        var self = this;
        var url = '/ajax/comedian';
        axios.get(url).then(function(response){
            self.comedians = response.data;
        });
    }
});

※注意が必要なのは、selfの部分です。Ajax通信の中身は関数になっているので、スコープの関係でthisを関数の外でselfに格納しています。

さぁ、いったんうまくデータ取得できているか確認してみましょう。

<div id="app">
    <h1>お笑い芸人リスト</h1>
    @{{ comedians }}
    <table></table>
</div>

※Laravelではひげ括弧{{ **** }}がBladeテンプレートエンジンに変換されてしまうので、@{{ ***** }}を使っています。

こんな感じになりました。
いい感じですね。

データ一覧をVueで表示する

では、最後の項目です。
取得したデータをテーブルで表示します。

データをループさせるv-forを使って実装してみましょう。

<table>
    <tr v-for="comedian in comedians">
    </tr>
</table>

そして、名前を表示する<td></td>タグを追加し、中身をv-textで格納するようにします。

<table>
    <tr v-for="comedian in comedians">
        <td v-text="comedian.name"></td>
    </tr>
</table>

はい、うまくデータ表示ができました。

では、最後にせっかくなんでbootstrapを読み込んでキレイなテーブルを表示したいと思います。

全コードはこちら。

<html>
    <head>
        <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
        <div id="app">
            <h1>お笑い芸人リスト</h1>
            <table class="table table-bordered table-hover">
                <tr v-for="comedian in comedians">
                    <td v-text="comedian.name"></td>
                </tr>
            </table>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
        <script>

            new Vue({
                el: '#app',
                data: {
                    comedians: {}
                },
                mounted() {
                    var self = this;
                    var url = '/ajax/comedian';
                    axios.get(url).then(function(response){
                        self.comedians = response.data;
                    });
                }
            });

        </script>
    </body>
</html>

ちなみに

comediansの中身が書き換わるごとに、テーブルの表示も自動で変更してくれます。
これがVueの大きな特徴、バインディング機能です。

なので、検索機能とかを実装するも比較的簡単に実装が可能です。

おわりに

ということで今回は、LaravelとVueの連携を記事にしてみました。
基本的な形は、reactでもangularでも同じだと思いますのでぜひ参考にしてみてくださいね。

ではでは〜。

 

この記事が役立ちましたらシェアお願いします😊✨