【Vue.js×Laravel】axiosでデータベースから取得、更新をする方法

この記事からわかること
- Vue.js×Laravelで作成されたアプリでデータベースを参照する方法
- データベースの値の取得や更新する流れ
- axiosの使い方(POST,GET)
- Vue.js側の記述とLaravel側の記述
index
[open]
\ アプリをリリースしました /
実現したかったこと
- データベースに格納されている値をVue.js側で表示する
- Vue.js側のテンプレートから送信された値をデータベースに格納する
今回実現したかったのは上記の2つです。ちなみに私の開発環境は以下の通りです。
- Laravel
- Vue.js
- MAMP(MySQL)
- Laravel/ui
- Vue Router
編集するページ
- web.php
- PersonController
- Component.vue
データベースに格納されている値をVue.js側で表示する
Laravelだけの場合「データベース→Laravel」のように直接値の取得ができました。しかしVue.jsではデータベースを操作できません。なので「データベース→Laravel→Vue.js」と言う流れを踏んで今回は解決することにします。
流れ
- データベースから値を取得(Laravel)
- 取得した値をURLからJSON形式(REST)で送信(Laravel)
- URL(JSONデータ)にアクセス(Vue.js)
- 取得したデータを表示(Vue.js)
REST(RESTful)とは
ここで肝となるのが2番の「取得した値をURLからJSON形式で送信」部分です。この機能は「REST(Representational State Transfer)」と呼ばれる仕組みを利用して実現可能です。RESTとは指定のHTTPメソッド(Postや get)のURLでアクセスされた場合のみ、条件に合ったデータをURLを介して取得することができます。例えば以下のURLにアクセスするとデモのユーザー情報のJSONデータを取得することができます。
JSONデータを返すデモページ:jsonplaceholder
この仕組みを使ってデータベースで取得したデータを、指定のメソッド(URL)でアクセスされた時に利用できるようにします。
このRESTが組み込まれているプログラムのことを「RESTfulなプログラム」と呼んだりします。
Laravel側でRESTを実装
まずはLaravel側でRESTを実装していきます。
やること
- ルーティング設定(web.php)
- データベース接続→値を取得
- returnでJSONデータを返す
今回は「/people
」でアクセスされた時にデータベース内のデータを取得できるように設定していきます。
まずLaravelのController側(ここではPersonController)にメソッド(people)を追加します。
PersonController.php
use Illuminate\Support\Facades\DB;
public function people(){
$users = DB::select('select * from Users');
return $users;
}
続いてLaravel側のルーティング設定(web.php)を行います。
web.php
Route::get('/people','App\Http\Controllers\PersonController@people');
HTTPメソッドはget
で「/people
」にアクセスされた時にPersonControllerのpeopleメソッドが実行されるように設定します。
これでアクセス時にデータベースから取得した値がJSON形式で取得できるようになります。
Vue.jsからRESTデータを受け取る
続いてはVue.js側からRESTで実現できたJSON形式の値を受け取ります。
これにはaxiosを使っていきます。
axios(アクシオス)とはHTTP通信を簡単にできるJavaScriptのライブラリです。
Laravel/uiで開発ベースを構築していた場合はデフォルトで組み込まれているのでインストールやimportする手間は必要ありません。 別途インストールが必要な場合はNode.jsの場合以下のコードでインストール可能です。
$ npm install axios
axiosを使って先程ルーティングしたURLにアクセスすればJSONデータを受け取ることができます。では実際のコードをVue.js側に記述していきます。
Component.vue
<template>
<div>
{{users.id}}
</div>
</template>
<script>
export default {
data() {
return {
users: [],
}
},
mounted() {
axios.get("/people").then((response) => (this.users = response.data));
},
}
</script>
axiosを使っての処理はmounted
フック(インスタンスがページに紐付いた時)に登録しておきます。ここでのget通信は非同期での処理になるので注意が必要です。処理を開始するのはこの場合mounted
フックのタイミングですが処理が終了するのはいつになるのかわかりません。ここでの返り値を使ってメソッドなどを記述しても正常に動作しないことがあるので注意してください。
$promise = axios.get('URL')
axiosはpromiseオブジェクト(非同期処理の結果(成功か拒否か))を返します。そのpromiseオブジェクトに対してメソッドチェーン(.で繋ぐ)でthenメソッドを実行します。
thenメソッドはpromiseオブジェクトの結果に応じで処理を分岐させられるメソッドです。第一引数に成功時に行いたい処理、第二引数に失敗時に行いたい処理を記述できます。
$promise.then(value => { 成功時に実行 }, reason => { 拒否に実行 });
ここでは成功時の処理のみ記述しています。
axios.get("/people").then((response) => (this.users = response.data));
thenメソッドの成功時の引数$response
の中にHTTP通信の結果(ステータスやデータ、URLなど)が格納されるのでresponse.status
、response.config
、response.data
などで必要なデータを取得できます。
ちなみにアクセスしたURLが間違っていたり、サーバーに不具合があったりで取得できなかったときはcacheメソッド
でエスケープ処理ができます。
.catch(error => console.log(error))
response.data
で取得できたJSONデータをVue.jsのデータ(this.users
)の中に格納しておきます。
this.users = response.data
あとは通常通りにデータを参照すればVue.js側のテンプレートの中からデータベースから取得したデータを引っ張ってくることができます。
Vue.js側から送信したデータをデータベースに格納する
次は先ほどの逆、Vue.js側から入力されたデータをデータベースに格納する方法をまとめていきます。
流れ
- input要素に入力されたデータをVue.js側で取得(Vue.js)
- axiosのPOST送信を使って指定URL(/post)に送信(Vue.js)
- 送信されたPOSTデータをLaravel側で処理(Laravel)
- データベースに格納
input要素に入力されたデータをVue.js側に格納
まずはVue.jsのテンプレート部分にinput要素を設置し、入力されたデータをVue.js側で操作できるようにしておきます。
Component.vue(上部)
<template>
<div>
<p>記事投稿画面(ユーザid:{{users.id}})</p>
<form>
<el-input
type="text"
placeholder="タイトル"
v-model="title"
/>
<el-input
type="textarea"
placeholder="質問内容"
v-model="question"
>
</el-input>
<el-button v-on:click.once="onPost" type="info" plain>投稿</el-button>
</form>
</div>
</template>
今回はライブラリ「Vue Element」を導入(el-inputなど)しています。
axiosでPOST通信
次に送信ボタンを押された時にaxiosを使ってPOST通信処理を行えるようにメソッドを登録しておきます。POSTの場合は第二引数に送信したいデータを渡します。
Component.vue(下部)
<script>
export default {
data() {
return {
users: [],
title: "",
question: "",
}
},
methods: {
onPost:function(){
axios.post("/post",{
user_id : this.users.id,
title : this.title,
question: this.question
},).then((response) => {
// ちゃんと送信できたか確認用
console.log(response);
})
.catch((err) => {
console.log(err);
});
},
},
mounted() {
axios.get("/people").then((response) => (this.users = response.data));
},
}
</script>
axios.post("URL",$data,)
これで指定したURLにPOST通信でデータを送信することができます。
あとは指定したURL側でデータベースに格納する処理を記述しておくだけです。
POSTされているURLのルーティングと処理
ここはLaravel側に記述していきます。
web.phpに指定したURL(/post
)でアクセスされた時のルートを記述します。Laravelのルーティングは上に記述されたルートから順に適応されますので順番には気をつけてください。
web.php
Route::post('/post','App\Http\Controllers\PersonController@createPost');
続いてコントローラー(PersonController)にcreatePostメソッド
を追加しデータベースへのインサート処理を記述します。これでこのURLにアクセスされた時にPOSTされているデータをデータベースの中に格納することができます。
PersonController.php
public function createPost(Request $request)
{
$param = [
'user_id'=>$request->input('user_id'),
'title'=>$request->input('title'),
'question'=>$request->input('question'),
];
DB::insert('insert into テーブル名 (user_id,title,question) values (:user_id,:title,:question)', $param);
}
axiosでPOST送信されたデータには$request->input('キー値')
で取得することができます。あとは取得したデータをSQL分に組み込めばデータベースにinput要素に入力された値を格納することができます。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。