Laravelとvue.jsを使ってアプリケーションを開発したいと思った時に最初に浮かんでくるのがどうやってLaravelのデータベースに入ったデータをvue.jsに渡して表示させるのかという疑問だと思います。

本文書ではLaravelとvue.jsどちらも初心者の人にもわかるように基礎からしっかり説明していきます。

事前準備:テーブルへのデータ登録

データベースからデータを取得するには、データの入ったテーブルが必要です。テーブルには、Laravelインストール直後でもphp artisan migrateコマンドで作成することができるusersテーブルを利用します。

usersテーブルへのデータの挿入は作業の効率を考えてLaravelのSeedingの機能を使います。

Seedingによるダミーデータ一括登録

Seeding入門者の人は、詳細は下記の文書を参考にしてください。本文書は詳しい説明しませんが説明通り実行するとusersテーブルにテストデータを挿入することができます。

まず、UsersTableSeederの作成を行います。このファイルの中で何件のダミーデータを作成するかを設定します。ファイルは、database/seedsの下に作成されます。


 $ php artisan make:seeder UsersTableSeeder
Seeder created successfully.

ファイルを開いて下記を追加してください。今回は、50件のダミーデータを挿入します。


use Illuminate\Database\Seeder;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
         $users = factory(App\User::class, 50)->create();
    }
}

ダミーデータに入る値の設定はUserFactory.phpで行います。UserFactory.phpはdatabase/factoriesの下に事前に作成されています。今回は初期設定のままで更新を行いません。


$factory->define(User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token' => Str::random(10),
    ];
});

次にdatabase/seedsの下にあるDatabaseSeeder.phpファイルのrunのコメントアウトを外します。


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

ここまでで設定は完了です。php artisan db:seedを実行するだけでダミーデータがusersテーブルに挿入されます。


 $ php artisan db:seed;
Seeding: UsersTableSeeder

ダミーデータの挿入確認

使っているデータベース、OSによって確認方法は異なりますが、共通の確認方法はphp artisan tinkerを使うことです。下記の通りに実行すればテーブルに挿入されたデータの確認を行うことができます。下記では挿入されたデータ件数と1件目の挿入データの確認を行っています。


laravel58 $ php artisan tinker
Psy Shell v0.9.9 (PHP 7.1.23 — cli) by Justin Hileman
>>> $users = App\User::all()->count();
=> 50 //件数を確認
>>> $users = App\User::all()->first(); // 1件だけデータを確認
=> App\User {#3010
     id: 1,
     name: "Mr. Billy Carroll IV",
     email: "zgottlieb@example.com",
     email_verified_at: "2019-06-12 02:12:24",
     created_at: "2019-06-12 02:12:24",
     updated_at: "2019-06-12 02:12:24",
   }

テーブルへのデータ挿入、確認を行ったので、次はvue.jsの設定を行います。

vue.jsの設定

今回使用するvue.jsの機能はシンプルなものばかりです。vue.jsの基本に不安がある人は下記の文書を参考にしてください。

vue.jsを使ってHello World

vue.jsが利用できる環境を作るために各種設定を行っていきます。ルーティングファイルweb.phpはデフォルト設定のままでwelcomeを指定しておきます。


Route::get('/', function () {

    return view('welcome');

});

welcome.blade.phpではcdnを使ってvueを読み込み、変数messageを使用して画面にHello World!!を表示させます。表示できればVueの初期設定は完了です。


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Laravel+Vue</title>
</head>
<body>
	<div id="app">
		@{{ message }}
	</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello World!!'
  }
})
</script>
</body>
</html>

axiosを使用してDBからデータ取得

vueからajaxリクエストを利用してデータを取得するためにaxiosを利用します。axiosを利用するためにwelcome.blade.phpにaxiosのcdnの追加を行います。


<script>
src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>

axiosを使ってデータベースからデータを取得するためにapi.phpに以下を追加します。/api/usersにアクセスすると挿入したダミーデータ50件分のデータが戻されます。


Route::get('users',function(){
	return App\User::all();
});

vue.jsのライフサイクルフックmountedで/api/usersにアクセスしてデータを取得します。mountedに設定を行うとブラウザで’/’にアクセスするとVueインスタンスの起動が開始して、その起動の流れの中でユーザの手を介することなく/api/usersからデータ取得が行われます。”/”にアクセスしたユーザがボタンをクリックしたりといった処理を行う必要はありません。


var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello World!!'
  },
  mounted: function(){
    axios.get('/api/users').then(response => console.log(response))
  }
})

Chromeのデベロッパーツールのコンソールを見るとaxiosによりusersのデータ取得できていることが確認できます。

axiosを使用して取得したデータ
axiosを使用して取得したデータ

ここまででLaravelとvue.jsとの連携が完了しました。

取得したユーザデータをリスト表示

取得したデータをul, liタグでリスト化するために下記のようにdataプロパティにusersを追加してaxiosで取得したデータをusersの中に保存します。


var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello World!!',
    users: []
  },
  mounted: function(){
    axios.get('/api/users').then(response => this.users = response.data);
  }
})

html文にはVueのv-forディレクティブを使用して取得したデータをリスト化します。


<ul>
	<li v-for="(user,index) in users" v-bind:key="index" >@{{ user.name }}</li>
</ul>

ブラウザで確認するとv-forディレクティブを使うことでリスト化できることが確認できます。

vueでユーザリストを表示
vueでユーザリストを表示

取得したユーザデータをテーブル表示

リスト表示からテーブル表示へと変更を行います。Laravel、vue.jsに特別の設定はありません。welcome.blade.phpのhtml文を書き換えるだけです。


<table>
	<thead>
		<tr>
			<th>ID</th>
			<th>ユーザ名</th>
			<th>E-mail</th>
		</tr>
	</thead>
	<tbody>
		<tr v-for="(user,index) in users" v-bind:key="index">
			<td>@{{ user.id }}</td>
			<td>@{{ user.name }}</td>
			<td>@{{ user.email }}</td>
		</tr>
</table>

下記のようにtable表示へと変わります。

取得したデータでtable表示
取得したデータでtable表示

bootstrapでテーブルを装飾

テーブルにstyle設定が行われていないと味気がないので、bootstrapで装飾を行います。cdnを使ってheadタグの中でbootstrapのcssを読み込みます。その他にbodyにもmarginを設定しておきます。


<head>
    <meta charset="UTF-8">
    <title>Laravel+Vue</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    <style>
    	body{
    		margin:20px;
    	}
    </style>
</head>

tableにbootstrapのclass設定を行います。classの値についてはbootstrapの公式サイトを確認してください。


<table class="table table-bordered">
	<thead  class="thead-dark">
		<tr>
			<th>ID</th>
			<th>ユーザ名</th>
			<th>E-mail</th>
		</tr>
	</thead>
	<tbody>
		<tr v-for="(user,index) in users" v-bind:key="index">
			<td>@{{ user.id }}</td>
			<td>@{{ user.name }}</td>
			<td>@{{ user.email }}</td>
		</tr>
</table>

bootstrapでclassを設定することでテーブルの雰囲気が大きく変わりました。

bootstrapのclassをtableに設定
bootstrapのclassをtableに設定

テーブルのデータ操作

テーブルの行の削除

vueを利用してテーブルの行の削除の方法を確認していきます。

新たにテーブルに削除列を追加します。


<table class="table table-bordered">
	<thead  class="thead-dark">
		<tr>
			<th>ID</th>
			<th>ユーザ名</th>
			<th>E-mail</th>
			<th>削除</th>
		</tr>
	</thead>
	<tbody>
		<tr v-for="(user,index) in users" v-bind:key="index">
			<td>@{{ user.id }}</td>
			<td>@{{ user.name }}</td>
			<td>@{{ user.email }}</td>
			<td><button class="btn btn-danger">削除</button></td>
		</tr>
</table>

削除ボタンが表示されることを確認してください。

テーブルに削除ボタンを追加
テーブルに削除ボタンを追加

ボタンにv-onディレクトリのclickイベントを設定し、ボタンがクリックされると行を削除するメソッドを追加します。メソッド名はdeleteRowとして、引数にはユーザを識別するidと行を識別するindexを設定します。indexにより行番号を取得することができます。


<td><button class="btn btn-danger" v-on:click="deleteRow(user.id,index)">削除</button></td>

vue.jsにmethodsプロパティを追加し、その中にdeleteRowメソッドを追加します。以下ではブラウザ上でのみ行を削除するコードになっています。実際のデータベース上のデータを削除する処理は記述していません。


var app = new Vue({
  el: '#app',
  data: {
    users: []
  },
  methods: {
  	deleteRow : function(id,index){
                console.log(id)
  		this.users.splice(index,1)
  	}
  },
  mounted: function(){
    axios.get('/api/users').then(response => this.users = response.data);
  }
})

IDが3, 5, 1の順番で削除を行い、ボタンを押した行が消え、コンソールにはその番号が表示されるかを確認します。

削除ボタンで行が消えるか確認
削除ボタンで行が消えるか確認

ブラウザのリロードを行うと元の状態に戻ります。ブラウザ上で行削除が正常に動作していることと削除したいユーザのIDが取得できたので、次はaxiosを使用してデータベースに保存されているデータ削除を実際に行います。


  methods: {
  	deleteRow : function(id,index){
  		axios.delete('api/users/' + id)
			.then((response) => {
			    console.log(response)
			    this.users.splice(index,1)
			}).catch((error) => {
				console.log(error)
			})	
  	}
  },

axiosからの削除リクエストを処理するためにapi.phpファイルに新規の行を追加します。


Route::delete('users/{id}',function($id){

	$user = App\User::find($id);

	$user->delete();

	return response()->json([
        'success' => 'user deleted successfully!'
    ]);
});

再度ブラウザを開き削除ボタンを押すと行が削除できるのは先程と同じですがリロードすると先程削除した行は表示されません。データベース内のデータが削除されたためです。