LaravelとVue.jsの学習用に簡単なプログラムを作ってみました。
完成品
このような画面を作ります。
urlを開くとタスクの一覧が表示されます。
filterに値を入力すると合致するタイトルの絞り込みができます。
これだけです。簡単ですね。
開発時間として60-90分くらいで完成させることができると思います。
それでは作っていきます。
Laravel開発環境の構築
今回はHomestadで開発環境を構築します。
※開発PCはMacを前提としますが、virtualboxとvagrantのインストール以外はほぼ同じだと思います。
# 必要ソフトのインストール
$ brew cask install virtualbox
$ brew cask install vagrant
# homesteadのセットアップ
$ vagrant box add laravel/homestead
$ git clone https://github.com/laravel/homestead.git
$ cd homestead
$ bash init.sh
# Homestead.ymlの編集とローカルのhotsファイルの編集
# ipはローカルpcのネットワークセグメントとは異なる値にする
$ vi Homestead.yml
# Homestead.ymlのipとsites_mapの対応を追記する
$ vi /etc/hots
Homesteadの起動と接続
# 起動
$ vagrant up
# 接続
$ vagrant ssh
※以降のコマンドはHomested上で実行します。
Laravelのプロジェクト作成
$ cd ~/code
$ laravel new
http://homestead.testをブラウザで開くと以下のような画面が表示されます。
Vue.jsのセットアップ
LaravelのプロジェクトでVue.jsを扱えるようにします。
# UIのscaffoldingなどに必要な公式パッケージのインストール
$ composer require laravel/ui
# ログイン機能の生成
# package.jsonにvueとvue-template-compilerが追加される
$ php artisan ui vue --auth
$ npm install
$ npm run dev
$php artisan ui vue --auth
によりログイン画面(/login)やユーザ登録画面(/register)が生成されます。
同時にログイン後の初期画面(/home)用の以下ファイルが生成されます。
- app/Http/Controllers/HomeController.php
- resources/views/home.blade.php
更に、web.phpにルーティングが追加されます。
# /homeのルーティングが追加される
# /homeへのgetリクエスト時にHomeController::index()を実行する。
Route::get('/home', 'HomeController@index')->name('home');
以降で/homeにアクセスするとタスクの一覧が表示されるようにしていきますが、一旦置いておきます。
モデルとマイグレートファイルの作成
DBにタスクテーブルを作成しLaravelで扱えるようにするためモデルとマイグレーションファイルを作成します。
# --migrationでモデルとマイグレーションファイルを同時に作成する
$ php artisan make:model Models/Task --migration
以下のファイルが生成されます。
- app/Models/Task.php
- database/migrations/YYYY_MM_DD_hhmmss_create_tasks_table.php
マイグレートファイルの編集
YYYY_MM_DD_hhmmss_create_tasks_table.phpに追記してタイトルと内容のカラムを追加します。
class CreateTasksTable extends Migration
{
public function up()
{
Schema::create('tasks', function (Blueprint $table) {
$table->bigIncrements('id');
//2カラム追加
$table->string('title');
$table->text('content')->nullable();//nullを許可
$table->timestamps();
});
}
マイグレートの実行
以下のコマンドを実行するとDBにTasksテーブルが作成されます。
$ php artisan migrate
ルーティングの追加
Laravelではページ用のルーティングとAPI用のルーティングが別のファイルになっています。
今はAPIのルーティングを追加するため以下のファイルに追記します。
- routes/api.php
# パスはapi/taskになる
# getリクエスト時にTaskControllerのindexメソッドを実行する
Route::get('/task', 'TaskController@index');
コントローラーの作成
タスクを扱うコントローラを作成します。後ほどこれにタスクの一覧をjsonで返すindex()という名前のメソッドを実装します。
# app/Http/Controllers/TaskController.phpが生成される
$ php artisan make:controller TaskController
APIの処理実装
index()メソッドを実装します。
今回はシンプルにTasksテーブルの全データをjsonで返すようにしました。
Task::all()
はCollectionという配列のラッパークラスにtasksテーブルの全データを
詰め込んだ状態で返します。
CollectionクラスのインスタンスをControllerのメソッドでreturnすると、Laravelが自動的にjsonに
変換してくれます。便利ですね。
<?php
namespace App\Http\Controllers;
use App\Models\Task;
use Illuminate\Http\Request;
class TaskController extends Controller
{
//indexメソッドを実装する
public function index()
{
//Tasksテーブルの全レコード取得
//Collectionクラスをreturnすると自動的にjsonにしてくれる
return Task::all();
}
}
これでタスクの一覧をjsonで取得するapi完成しました。
テストデータの自動作成
次にテスト用のTasksテーブルのデータを自動作成できるようにしていきます。
今回はやりませんがテスト自動化をする場合に便利です。
とりあえず手動でデータ追加するという人はここを飛ばしても問題ありません。
ファクトリーの作成
ファクトリーは自動作成するデータの値(範囲や形式)を定義することができます。
# ファクトリーファイルの作成
$ php artisan make:factory TaskFactory
フェイクデータを簡単に作成できるFakerを使用します。
様々な種類のデータを作成するためのメソッドが用意されています。
参考 [Laravel5.1]Fakerチートシート
use App\Models\Task;
use Faker\Generator as Faker;
// 作成データの定義
$factory->define(Task::class, function (Faker $faker) {
return [
'title' => $faker->word, //言葉
'content' => $faker->sentence, //文章
'user_id' => $faker->numberBetween(1, 5)//1-5の数値
];
});
シーダーの作成
次にデータ作成を実行するシーダーを作ります。
# シーダーファイルを作成
$ php artisan make:seeder TasksTableSeeder
以下のように記述すると先程作成したファクトリーが呼び出され、その定義に従ってデータが作成されます。
use Illuminate\Database\Seeder;
use App\Models\Task;
class TasksTableSeeder extends Seeder
{
public function run()
{
//ファクトリーの定義に従って20件のデータを作成
factory(Task::class, 20)->create();
}
}
次に$ php artisan db:seed
を実行するとTasksTableSeeder
が実行されるようにDatabaseSeeder
に追記します。
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
//追記
$this->call(TasksTableSeeder::class);
}
}
ここまでできたら以下のコマンドを実行するとシーダーが実行されてデータが自動作成されます。
ドキュメントには以下のような記載があり、実際にこれをしないとシーダー実行時にエラーになります。なぜ必要になるのかまだ私はしっかりと理解できていないので、知っている方教えていただけると幸いです。
シーダクラスを書き上げたら、Composerのオートローダを再生成するために、dump-autoloadコマンドを実行する必要があります。
$ composer dump-autoload
シーダーを実行します。これでデータが自動作成されます。
$ php artisan db:seed
タスク一覧画面の作成
Vueコンポーネントの作成
タスクの一覧を表示するコンポーネントを作ります。
# ファイル作成
$ touch resources/js/components/TasksComponents.vue
以下の通りに記述します。やっていることは大きく以下の3つです。
- apiからタスクの一覧を取得しtasksに格納
- input textの入力値をタイトルに含むタスクだけを抽出
- 抽出したタスクを一覧表示
<template>
<div class="container">
<!-- v-modelで変数と入力値を同期させる -->
<input v-model="condition" class="form-control filter" type="text" placeholder="filter">
<div class="list-group">
<!-- v-forで条件に合致したタスクを繰り返し表示する -->
<div v-for="task in matched" :key="task.id"
class="list-group-item list-group-item-action flex-column align-items-start">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">{{ task.title }}</h5>
<small class="text-muted">{{ task.created_at }}</small>
</div>
<p class="mb-1">{{ task.content }}</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: "TasksComponents.vue",
data: function () {
return {
condition: null, //フィルタ条件
tasks: [] //タスクの配列
}
},
created() {
//インスタンス生成時にapiからタスク一覧を取得して変数に格納
axios.get('/api/task').then(response => {
this.tasks = response.data
})
},
computed: {
matched: function () {
//conditionの値が変更されると自動的に呼び出される
return this.tasks.filter(function (element) {
//タイトルにcondionの値を含むものでフィルタ
return !this.condition || element.title.indexOf(this.condition) !== -1
}, this)
}
}
}
</script>
<style scoped>
.filter {
margin: 1em 0em;
}
</style>
コンポーネントの登録
先程作成したコンポーネントをresources/js/app.js
に登録します。
require('./bootstrap');
window.Vue = require('vue');
//ここを追記 コンポーネントの登録
Vue.component('tasks-component', require('./components/TasksComponents.vue').default);
const app = new Vue({
el: '#app',
});
コンポーネントの呼び出し
コンポーネントを登録したので呼び出せるようになりました。
resources/views/home.blade.php
を以下のように編集します。
{{ --@からはじまるのはbladeの構文 --}}
@extends('layouts.app')
@section('content')
{{-- コンポーネントを呼び出す --}}
<tasks-component></tasks-component>
@endsection
以上でコーディングは完了です。
実行
開発環境で実行するには以下のコマンドを実行します。
アセットの関連ファイル変更時に自動的にコンパイルしてくれます。
# ファイルの変更時にアセットを自動的にコンパイルする
$ npm run watch
http://homestead.test/home
にアクセスするとタスクの一覧が表示されます。
以上