はじめに
Vue.jsでLaravelのDBを弄る方法をまとめました。
前回はAjaxで非同期処理を行っていましたが、今回はAxiosを使った実装理解をしていこうと思います。

※前回記事
プロジェクトの作成
事前準備
Axiosを使うまでの実装。
※以下のやり方を踏まえて、色々な編集工程を極限までそぎ落としてみました。
・TodoController作成。indexアクションメソッドを追記。(welcomeビューをそのまま使います)
php artisan make:controller TodoController
編集
public function index() { return view('welcome'); } }
・ルーティングの設定。web.phpを編集。Webルートの制限が便利です。
<?php Route::get('/{any}', function () { return view('welcome'); })->where('any', '.*');
全てのURLでwelcome.blade.phpを表示するようになります。
・マイグレーションファイルの作成
php artisan make:migration create_todos_table
編集
Schema::create('todos', function (Blueprint $table) { $table->bigIncrements('id'); // 削除・更新で重要 $table->string('todo'); // $table->integer('user_id'); // ここを削除 // $table->timestamps(); //今回は時間も不要なので削除⇒Axiosの実装で必要なことがわかりました。 });
※6.8だとuser_idの紐づけはデフォルトで記述されていないのでそのままでOKです。
反映
php artisan migrate
・モデルの作成
php artisan make:model Todo
・Vue.jsの実装
npm i npm run dev npm run watch
・welcome.blade.phpの編集
<script src="{{ asset('js/app.js') }}" defer></script> <meta name="csrf-token" content="{{ csrf_token() }}"> // post送信時にトークンが必要 <div id="app"> <h2>TODO アプリケーション</h2> <example-component></example-component> </div>
現状こんな感じです。

Laravel6.8だとデフォルトでVue.jsが入っていません。package.jsonを編集してからインストールする必要があります。
package.jsonに追記
"vue": "^2.5.17",
js/app.jsの編集
require('./bootstrap'); window.Vue = require('vue'); Vue.component('example-component', require('./ExampleComponent.vue').default); const app = new Vue({ el: '#app' });
js/ExampleComponent.vueの作成
今回編集が不要な部分
・Karnel.phpでの認証保持用(セッション・クッキー)のミドルウェア設定。
・Todoモデルの編集。(ユーザーとのリレーション設定は今回なし。)
機能実装
・ExampleComponent.vueの編集
※ここは前回の完成コード流用。
・api.phpの編集
<?php Route::get('/','TodoController@get'); Route::post('/','TodoController@post'); Route::delete('/{id}','TodoController@delete'); Route::put('/{id}','TodoController@update');
・TodoControllerの編集
※前回のコードから認証部分のコードを削除。


Axiosの実装
ここからAjaxからAxiosのコードに変えていきます。
axiosはブラウザやnode.js上で動くPromiseベースのHTTPクライアント。
第一引数にパラメータ付きのURLを指定し、.then()で通信が成功した際の処理を書く。
response.dataにデータが入る。

データの取得
mounted() { axios.get('/api') .then(res =>{ this.todos = res.data; }) }

<?php use App\Todo; Route::get('/',function(){ return response()->json(Todo::all()); });

データの削除
※データの追加を最初に試したところ全然できなかったので、削除に挑戦。
deleteTodo(id) { var data = {}; axios.delete("/api/" + id, JSON.stringify(data)).then(() => { this.getTodoList(); }); },

また。JSON.stringfy()メソッドの記述はなくても機能しました。これはデータが1つしか入っていないからかもしれません。
データの追加
※追加の実装はかなり苦戦しました。
addTodo() { var data = { todo: this.todo_form // insertされる内容。カラムに合わせる。 }; axios.post('/api', data).then(() => { this.getTodoList(); }); },

備忘録:【Laravel x Vue.js】SPAクイズアプリケーションを作ってみよう! 最初はこちらの教材(7-5から)を参考にしましたが、POST送信に関してはformタグでURL遷移する実装(会員登録後TOPページへ移動。)になっていました。
データの更新
以下でとりあえずPUTメソッドが使えることを確認。
updateTodo(id) { axios.put("/api/" + id, {todo: "edit"}).then(() => { this.getTodoList(); }); },
その後チュートリアル通りfilterメソッドを使って実装。
updateTodo(id) { var data = { todo:this.todos.filter(function(value){return value.id === id})[0].todo }; axios.put("/api/" + id, data).then(() => { this.getTodoList(); alert('更新が完了しました。') }); },

完成
https://twitter.com/masaru_pg/status/1252201555056451584
躓いた点
①トークンの実装方法がわからず。⇒結果として実装できていないもののなぜか動く。
(コンソールで500エラーを確認。トークンの実装周りが原因だと思っていたが違った。)

追記:デフォルトではAPIはトークンを使用しない設定になっているっぽい。Karnel.phpで設定弄れる。クッキー周りの対応法はこちらの教材が詳しく扱ってる。
・GoogleConsoleのNetworkタグでapi通信の挙動を確認したところ以下のような内容の記述。
message: “SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘updated_at’ in ‘field list’ (SQL: insert into `todos` (`todo`, `updated_at`, `created_at`) values (テストだよよ, 2020-04-20 07:54:19, 2020-04-20 07:54:19))”
exception: “Illuminate\Database\QueryException”
file: “C:\xampp\htdocs\memo_noauth6.8\vendor\laravel\framework\src\Illuminate\Database\Connection.php”
line: 669
⇒updatad_atカラムがないことでエラーが起きていたので、カラムを追加しなおしたところ動いた。これは思わぬ落とし穴でした。。。(おそらく根本的なDatabaseの設定を弄れば変えられると思うけど。。。)
②PUTメソッドが使えない。※この後POSTメソッドに変えても同様のエラー。⇒axiosメソッドのルーティングでapiの後ろに/入れ忘れ


・Laravelでは変数を返却すると自動的にJSONに変換して表示を行うそうです(教材6-3参考)。
Route::get('/',function(){ $todo = Todo::all(); return $todo; });
・見通しを良くするためにTodoControllerに記載していたアクションメソッドは全てapi.phpで記載しました。
おわりに
Ajaxから本来実装が簡単であるはずのAxiosに置き換えるだけでかなり苦戦してしまいました。
ですが、おかげでLaravel×Vue.jsの理解が深まりました。
やっとこさLaravel×Vue.jsのアプリ制作にとりかかれそうです。
また、今回トークン処理(+Vue.js側での認証状態の維持)の対応を踏まえるとログイン/会員登録機能はLaravel側で実装したほうが良い気がしました。
振り返ったらHC教材ではVuexまで活用して実装しているし、TechpitSPA開発教材(7-5)も同じくトークン処理で記述が多め。
勉強がてらならいいけど、実際に使うとなると実装も難しいしかえって管理が大変そう。
しかもログイン/会員登録画面って別でページ用意すること多いし、処理後トップページなどに遷移するケースがほとんど。
一つ目の課題は、ページをリロードしたときに認証状態が維持できない点です。
試しにログインした状態でページをリロードしてみてください。ヘッダーとフッターにログインリンクが表示され、ログアウト状態に戻ってしまうはずです。
ページをリロードすると Vue アプリケーションが再作成されるので、当然 user
ステートも初期値である null
に戻ってしまいます。それで見た目はログアウトしてしまうのです。
ただしサーバサイドのセッション的にはまだログインしているので、もう一度ログインしようとするとユーザーデータではなく /home
へのリダイレクトレスポンスが返却されます。そのためログインしているような見た目だがユーザー名が表示されないという中途半端な表示になります。
この挙動を修正するために、ログインユーザーを返却する API を追加して、最初にログインユーザーを取得してから Vue アプリケーションを生成するように起動スクリプトを変更しましょう。
また、一応 /home
へリダイレクトさせるミドルウェアも修正しておきます。
参考
公式
参考
Laravel + Vue.js + axiosで非同期postリクエストを送ろうとし時のハマったポイント(全部うっかりミス)をまとめた 追加処理の実装
laravel で vue.js , axios を使う こちらは取得のみの実装
Documentインターフェース ⇒あらゆる種類の文書に対して共通のプロパティやメソッドを提供。
vue.jsを使ってaxiosを学ぶ 一通りCRUDの解説あるが難しい。
vue.js と axios を使って Web API にアクセスする POSTの実装。むずい。。。
Laravel + Vue.js + vue-router + axios.postでSPA作成(記事投稿機能) anyの実装も参考になる。
axiosライブラリを使ってリクエストする axiosは第二引数に登録・更新データを持たせる。
Laravelで405や419エラーに遭遇した場合の対処法 ルーティングの定義漏れ
Google Developper tool を使いましょう。
・500番台→パスは合っているがphp の処理中にエラーが発生している
・400番台→パスが間違っている
・200→処理は成功している
axiosのヘッダーにtokenを埋め込んで常時使えるようにする
ajaxでエラーが出てしまう。【laravel5】 Ajaxだとトークンでの処理解決方法が結構出てくる。
Laravel5でのAjaxでPOSTするときのValidation(Axios利用している。)
Laravel + Vue で問い合わせフォームをつくる メール送信機能でCSRF,TOKENの実装はなし。
Laravel + Vue.js + axiosでメール送信する方法を解説 上に同じ。
Laravel + vue.jsでシンプルファイルアップロード Axios側のトークン設定の記述なし。
Laravel5.6とVue.jsで簡単なシングルページアプリケーション POSTメソッドに関してaxiosで特に配慮するような記述はない。