【Ajax(API)の実装】Laravel+Vue.jsでのDB連携

はじめに

前回試したチュートリアルのコードを紐解いてLaravel+Vue.jsの理解を深めていきます。

※随時更新

【感想】Laravel+PostgreSQL+Vue.jsでSPA開発【チュートリアル】

コードの簡略化

チュートリアルのコードが完成した状態からスタートしています。

まずはコードが自分が見て理解がしやすいように修正しました。

トップ画面をログイン有無にかかわらずtodo.blade.phpにする。

①welcome.blade.phpを削除

補足
welcome.blade.phpはほかのビューと依存関係がない完全に独立したビューなので削除しても支障なし。逆に、それ以外のビュー(認証系のビューなど)は全てlayouts/app.blade.phpを@extendsしてるので注意。

②web.phpの編集

※これで全文です。

<?php
Auth::routes();
Route::get('/','TodoController@index');
ちょび
ミドルウェアによるアクセス認証もなくしました。Auth::routes()をなくすとログイン機能自体が処理できなくなるのでこれだけは残す必要があります。

コンポーネント名の変更

ExampleComponent.vueからTodo.vueにします。

app.jsの編集

※bootstrap.jsの読込も削除。

window.Vue = require('vue');

Vue.component('todo', require('./components/Todo.vue').default);

const app = new Vue({
    el: '#app'
});
todo.blade.phpの編集
@extends('layouts.app')
@section('content')
<div>
  <Todo />
</div>
@endsection
ちょび
これも勉強だと思って試してみました。app.jsとかデフォルトだとコメントアウトの文章が長すぎて把握しづらい。。。

Bootstrapを適用外にする。

①Bootstrap適用外にする。

ちょび
今まで全然使ってこなかったから気づかなかったけどjQueryとBootstrapってデフォルトでpackage.jsonに入ってるんですね。

resources/asset/js/bootstrap.jsでjs側のimportを削除。

try {
    window.Popper = require('popper.js').default;
    window.$ = window.jQuery = require('jquery');
    require('bootstrap');
} catch (e) {}

resources/sass/app.scssでcss側のimportを削除。

// Bootstrap
@import '~bootstrap/scss/bootstrap';
ちょび
こいつをミュートしたらBootstrapが適用されなくなりました!個人的にはこっちの方が落ち着きます。笑

②Bootstrap関連のクラスの削除

対象はTodo.vue、app.blade.php。

Bootstrapの影響でビュー側にクラスが付いたり、divで囲ったりと冗長になっている部分があるのでそぎ落とします。

Todo.vue

app.blade.php

ちょび
だいぶすっきりしました◎認証系もBootstrapのコードがガンガン記載されてますがこちらはステイ。

コードの読み解き(Vue.jsからDBへのCRUD)

Todo.vueからDBへのCRUDの把握をしていこうと思います。

ちょび
CRUDはCreate(生成)、Read(読み取り)、Update(更新)、Delete(削除)の略です。

ルーティング整理

①認証系のリダイレクト先をすべてホームディレクトリに変更。

②api.jsのapiをホームディレクトリに変更。

③api.phpから/todoの部分を削除。

DB連携で重要なファイル一覧。

・api.php

ここでコントローラーに定義したアクションの呼び出しをしてます。

※デフォルトではAPIでユーザー認証を使う場合の記述もありますが、今回は削除。

※教材ではauth.api(ミドルウェア)の実装もしていますがこちらも省略。

<?php
Route::get('/','TodoController@get');
Route::post('/','TodoController@post');
Route::delete('/{id}','TodoController@delete');
Route::put('/{id}','TodoController@update');
ちょび
web.php側にもRoute::get(‘/’,’TodoController@index’);の記載が最低限必要です。
補足

http://127.0.0.1:8000/apiへアクセスするとログインユーザーに紐づくデータが取得できていることが確認できます。

URLに/apiと記述するとapi.phpのURLになるんですね!!

・Karnel.php

ミドルウェアグループでクッキー、セッションの有効化。

注意
ここを有効化しないとログイン情報の保持ができなくなります。
ちょび
ログイン機能を実装しない場合はなくても機能するのかが気になりました。

・Todo.vue(+api.js)

api.jsではAPIを叩くモジュール(sendメソッド)とapi定数を定義しています。

ちょび
今回は僕が理解しやすいようにapi.jsをTodo.vueにがっちゃんこしました。また、この教材ではVue.jsで定番のaxiosは用いずに素のJS(Ajax)コードで書かれていますね!

・TodoController

<?php
namespace App\Http\Controllers;
use App\Todo;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class TodoController extends Controller
{
    public function index() {
        return view('todo');
    }
    // メインビューの表示
    public function get(){
        return response()->json(Auth::user()->todos()->get());
    }
    // 全件表示
    public function post(Request $request){
        $todo = new Todo();
        $todo->todo = $request->todo;
        $todo->user_id = Auth::id();
        $todo->save();
        return response("OK", 200);
    }
    // 1件追加
    public function delete($id){
        Todo::find($id)->delete();
        return response("OK", 200);;
    }
    // 1件削除
    public function update(Request $request,$id){
        $todo = Todo::find($id);
        $todo->todo = $request->todo;
        $todo->save();
        return response("OK", 200);
    }
    // 1件更新
}
ちょび
ここまでファイルを見渡して、3つのファイルを深堀したいなと思いました。①TodoController.php②api.php③Todo.vue

Ajaxの理解

上記の洗い出しで今回のチュートリアルではAxiosを使わずにAjaxを利用していることが確認できました。

ですので、Ajaxの理解を深めていこうと思います。

Ajaxアプリを実装する場合に必要なファイル

①クライアント側で動作するファイル(Todo.vue)
②サーバー側で動作するファイル(Laravel側)

JSON.stringifyメソッド:JSの配列、オブジェクトをJSON文字列に変換。

ちょび
その他、いろいろとコメントでコードに追記しながら分析しました。

ちょび
コントローラからJSON形式でVue.js側に送る際、response()->json()で返さなきゃいけないのね。json_encodeだと渡せないみたい。ややこい。

★わかったこと★

・ToDoリストの表示:getTodoListメソッドをDOMが生成された直後にmountedフックで呼び出し。

・追加・削除(引数にid)・更新ボタン(引数にid)でメソッドを実行。同名の関数がapi定数にオブジェクトで登録されているので呼び出し(=send関数内の非同期処理Ajaxの実行)。api.phpからTodoControllerのアクションメソッドを実行し、その値を返却。非同期処理終了後、リストを再取得して最新化。

・JSとPHPでのやりとりはJSON形式に変換して行う。

・api定数の各関数のsendメソッドの引数にリクエストメソッドを与えてる(GET、POST、PUT、DELETE)。これがapi.phpのRouteファサードに連動されてる。ここから更にコントローラへ処理アクションを呼び出し。

おわりに

個人的にLaravelのデフォルトのコードは諸々、既にガッツリBootstrapが適用されていて、弄りにくいなと感じました。

デザインはガッツリそぎ落として生成してくれたほうがありがたいな~。

そして、やっとVue.jsでLaravelのDBを弄る方法がわかりました◎

予想に反して、AxiosでもjQueryでもなく、まさかの素のAjaxでの理解でしたが、このコードを活かしてAxiosへの変換&理解に次は挑戦したいです。

豆知識

インデント自動整形

Alt+Shift+Fでインデントの自動整形できることを最近知りました。

デフォルトで作られるファイルは軒並みインデントが4になってます。

個人的に見づらいので。。。

プロジェクト直下の/editorconfigの設定を2にします。

加えてAlt+Shift+Fで自動整形。

見やすくなりました✌

参考

Laravel5.7: Bootstrapを使ってレイアウトを作る

Laravel5.5インストールからBootstrap4を導入するまで

【メモ】XMLHttpRequestのイベントについて

try…catch 文

TO DO リスト 表示のみ (Vue.js + Ajax + Laravel) こちらではjQueryの$.ajax()を利用している。

getElementsByClassNameとgetElementByIdの返り値の違い

getElementByIdは指定したidの要素が返り値になる。

getElementsByNameの返り値はname属性の要素でリストで取得する。

getElementByIdとgetElementsByNameの違い

仮想DOMは本当に“速い”のか? DOM操作の新しい考え方を、フレームワークを実装して理解しよう

[JavaScript] オブジェクトの基礎

[Laravel]レスポンスをJSON形式で返す方法2つ

【Laravel】【PHP】json_decode(配列化)/ json_encode(JSON化)

コメントを残す