
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、このブログでは長らくLaravel
とVue
について記事を公開してきました。
どちらも「シンプルなのに高機能」という点が人気の理由だと思うのですが、そんな両者は、ときに「連携」してデータを渡す必要が出てきます。
例えば、Laravel
でDBからデータを取得してVue
で表示するような場合です。
そして、そんな連携をする場合、少しテクニックが必要になったりします。
そこで
今回は、Laravel
とVue
を連携させる方法をまとめてみることにしました。
ぜひ皆さんの学習に役に立ちましたら嬉しいです
「レトルトのパスタソースが
こんなにウマいとは」
開発環境: Laravel 8、Vue 3
目次 [非表示]
直接 Vue のコードに埋め込む場合
Laravel
のテンプレート・エンジン「Blade」を使って、Vue
にデータを渡します。
おおまかに言うと、コントローラーで次のようにビューを呼び出してします。
// 省略
class HomeController extends Controller
{
public function laravel_vue_cooperation() {
return view('laravel_vue_cooperation')->with([
'string' => '文字列',
'number' => 1,
'boolean' => true,
'array' => ['太郎', '次郎', '三郎'],
'collection' => collect([
'太郎',
'次郎',
'三郎'
]),
'null' => null,
'model1' => User::find(1),
'model2' => User::select('name')->take(3)->get()
]);
}
// 省略
そして、データを以下のようにセットすることになります。
<!-- Bladeファイルの中です -->
<script>
Vue.createApp({
data() {
return {
// JavaScript内にデータを埋め込む
}
}
}).mount('#app');
</script>
では、各データタイプの埋め込み方をひとつずつ見ていきましょう
文字列
文字列の埋め込みは、連携の基本になります。
data() {
return {
string: '{{ $string }}' //
ここ
}
}
ここでまず重要なのが{{
と}}
で囲まれた部分です。
この部分はBlade
がPHPの変数と入れ替えてくれますので、今回の例で言うと「文字列」に入れ替わります。
そして、次に{{ $string }}
がシングルクォートで囲まれている部分も重要です。
なぜなら、$string
が「文字列」に入れ替わった後のことを考えないといけないからです。
つまり、このシングルクォートはJavaScript
のために書いています。
では、実際に実行後のコードを見てみましょう。
data() {
return {
string: '文字列',
}
}
このようにシングルクォートが表示され、うまくJavaScript
側と連携していますね。
もしシングルクォートを書かない場合、以下のようになりエラーが発生することになります。
data() {
return {
string: 文字列, //
これはエラーになります。
}
}
ちなみに、Bladeの{{ ... }}
を使えば、以下のように初期値をつくることもできるので便利ですよ
data() {
return {
string: '{{ $string ?? '初期値' }}'
}
}
この例の場合、$string
が存在しない場合、自動的に初期値が表示されることになります。
※「存在しない場合」というのはnull
の場合です。空白の場合はそのまま表示されるので注意してください。
data() {
return {
string: '初期値' //
初期値が採用されます
}
}
数値の場合
数値の場合もほぼ文字列のときと同じです。
data() {
return {
number: {{ $number }}
}
}
ただし、厳密に「数値」としてデータを渡す場合、文字列のようにシングルクォートで囲んではいけません。
なぜなら、シングルクォートで囲んでしまうと、実行後のコードは以下のようになってしまうからです。
data() {
return {
number: '1' //
これは「文字列」として扱われます
}
}
なお、IDEやテキストエディタによっては、
number: {{ $number }}
と書いてしまうと、JavaScript
のコードとしては間違っているのでエラーがでる場合があります。
もしそれが気になる場合は以下のようにするといいでしょう。
data() {
return {
number1: parseInt('{{ $number }}'), //
int型の場合
number2: parseFloat('{{ $number }}'), //
float型の場合
}
}
これでエラーはでなくなりますし、変数の中身を明確にしているので、よりエラーが発生しにくくなるでしょう。(parseInt
、parseFloat
は型を変換するJavaScriptの関数です)
Boolean(true or false)の場合
Boolean型
を埋め込む場合は少し注意が必要です。
なぜなら、ここまででみてきたように埋め込んでしまうとtrue
やfalse
ではなく数値になってしまうからです。
data() {
return {
boolean: {{ $boolean }} //
「1」になる
}
}
そのため、明確にBoolean
として埋め込むには次のようにします。
data() {
return {
//
PHPの分岐を使う
boolean: {{ ($boolean) ? 'true' : 'false' }}
}
}
配列
配列を埋め込む場合は、以下のようにします。
data() {
return {
array: @json($array) //
JSONにしてくれる
}
}
ただし、@json
はLaravel 5.5
以降で使える書き方ですので、それ以外の場合は、json_encode()
を使ってください。
data() {
return {
array: {!! json_encode($array) !!} // 配列をJSONへ変換
}
}
なお、お気づきの方もいらっしゃるかと思いますが、json_encode()
を使う場合、{!!
と!!}
で囲んでいます。
なぜなら、通常どおり{{ ... }}
を使ってしまうと、ダブルクォートがエスケープされてしまい、JavaScriptのコードとしてエラーになってしまうからです。
実際の例を見てみましょう。
まずは、{!!
と!!}
で囲んだ正しい結果です。
data() {
return {
// 正しくダブルクォートで囲まれています
array: ["\u592a\u90ce","\u6b21\u90ce","\u4e09\u90ce"]
}
}
次に間違った例です。(エラーになります)
//
これは間違った例です。
data() {
return {
// ダブルクォートがエスケープされて「"」になっています...
array: ["\u592a\u90ce","\u6b21\u90ce","\u4e09\u90ce"]
}
}
コレクション、モデル
コレクションやモデルの場合も配列とほぼ同じように埋め込むことができます。
data() {
return {
collection: @json($collection)
}
}
なお、Laravel 5.4
以下の場合は次のようにしてください。
data() {
return {
collection: {!! $collection !!}
}
}
※ 実は、Laravel
のコレクション・モデルはjson_encode()
を使わなくても自動でJSON
化してくれるんですね
元も子もない話
なお、実は元も子もない話があって、なんと、どんなデータタイプの値であっても@json
に入れてあげればうまくいくんですね。
こんなカンジです。
data() {
return {
string: @json($string),
number: @json($number),
boolean: @json($boolean),
array: @json($array),
collection: @json($collection)
}
}
ただし、全てに@json
を使ってしまうと、変数の中身が分かりにくくなりますし、IDE
の方でJavaScript
のエラーがでるので、個人的にはこれまで紹介した個別の書き方をしています。(この辺は好みもあるかもしれません)
Ajaxを使う場合
Laravel
とVue
を連携させるもうひとつの方法が、Ajax
でデータを取得しVue
へセットするという方法です。
では、実際の方法を順を追ってみていきましょう。(なお、Ajax
通信にはaxios
を使います)
Laravelでデータ部分をつくる
まずは、Laravel
でJSON
データを提供する部分をつくります。
ルートをつくる
では、ルートです。
routes/web.php
Route::get('json_data', [HomeController::class, 'json_data'])->name('json_data');
※ なお、メソッドをGET
にしていますが、Ajax
でパラメータと一緒に送信する場合はPOST
の方がいいかもしれません。
通常通りの書き方ですが、name()
で「json_data」という名前をつけていることを覚えておいてください。後ほどVue
側で使います。
コントローラーをつくる
続いてコントローラーです。
まずは以下のコマンドでHomeController
をつくります。
php artisan make:controller HomeController
すると、ファイルが作成されますので、中身を以下のように変更してください。
app/Http/Controllers/HomeController.php
<?php
namespace App\Http\Controllers;
// 省略
class HomeController extends Controller
{
public function json_data() {
$string = '文字列';
$number = 12345;
$boolean = true;
$array = ['太郎', '次郎', '三郎'];
$object = [
'key_1' => 'value_1',
'key_2' => 'value_2',
'key_3' => 'value_3',
];
return [
'string' => $string,
'number' => $number,
'boolean' => $boolean,
'array' => $array,
'object' => $object
];
}
// 省略
この中では、以下のタイプのデータをそれぞれ配列にしてreturn
しています。
- 文字列
- 数値
- 真偽値(Boolean)
- 配列
- オブジェクト ※
※PHPの場合「連想配列」と呼んだほうがいいでしょうが、今回はJavaScript
側に合わせて「オブジェクト」と呼びます。
ちなみに、Laravel
でJSON
のデータを返したい場合は、わざわざビューを作らなくてもコントローラーから値をreturn
するだけでOKです
では、実際の表示を見てみましょう。
うまくJSON
データが表示できています
Vueでデータ取得して変数へセットする部分をつくる
では、Vue
側から先ほど作ったJSON
データを取得し、変数へセットする部分をつくっていきましょう。
以下のようなビューをつくってください。(重複するので、ルートとコントローラーは省略しますがお好みで作ってください)
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
</head>
<body>
<div id="app">
<!-- ③ 変数の中身を表示 -->
<span v-text="string"></span>
<span v-text="number"></span>
<span v-text="boolean"></span>
<span v-text="array"></span>
<span v-text="object"></span>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
<script src="https://unpkg.com/vue@3.0.2/dist/vue.global.prod.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<script>
Vue.createApp({
data() {
return {
string: '',
number: 0,
boolean: false,
array: [],
object: {}
}
},
methods: {
getJsonData() { // ② AjaxでJSONを取得
const url = '{{ route('json_data') }}'; // ここでもLaravelと連携
axios.get(url)
.then(response => {
this.string = response.data.string;
this.number = response.data.number;
this.boolean = response.data.boolean;
this.array = response.data.array;
this.object = response.data.object;
});
}
},
mounted() {
this.getJsonData(); // ① データ取得メソッドを実行
}
}).mount('#app');
</script>
</body>
</html>
では、順を追ってみていきましょう。
① データ取得メソッドを実行
mounted()
はページが表示されたらすぐに実行されますので、ここでJSON
データ取得用のgetJsonData()
を呼んでいます。
② AjaxでJSONを取得
axios
を使ってLaravel
側に作ったJSON
データを取得する部分です。
ここで注意していただいきたいのが、URL
をLaravel
のヘルパー関数route()
で取得している部分です。こうすることによって、もし今後ルートのURLが変更になってもこのコードは変更しなくて済むようになります。
そして、axios
の場合、通信が成功するとresponse.data
からデータを取得できますので、それぞれのデータをVue
の変数へセットしています。
③ 変数の中身を表示
ここはVue
変数の中身を確認するためにつくりました。
Ajax
通信が早い場合はあまりわかりませんが、以下の順序で変化します。
- はじめは何も表示されていない
- 変数がセットされると中身が表示になる
おまけ:BladeでVueの変数を表示する場合
ご存知のとおり、Blade
でPHPの変数
を表示する場合は、{{
と}}
で囲むことになっています。
<span>
<!-- 変数と入れ替わる -->
{{ $value }}
</span>
しかし、Vue
の場合はどうでしょうか。
そうです。同じく{{
と}}
で囲むことになっています。
そのため、Blade
の中でVue
を使う場合、気をつけないとエラーが発生してしまいます。
では、どのようにすればVue
のために{{
と}}
を用意することができるでしょうか。答えは、「@」です。
以下のように先頭に@
をつけると、そのまま表示することができるんですね。
<span>
<!-- ここはそのまま表示されます -->
@{{ javaScriptValue }}
</span>
つまり、実行すると以下のようになります。
<span>
{{ javaScriptValue }}
</span>
なお、個人的には混同しなくてすむので、v-text
を使うことが多いです
<!-- 上と同じ結果になります。 -->
<span v-text="javaScriptValue"></span>
おわりに
ということで、今回はPHP
、JavaScript
界で人気のパッケージLaravel
とVue
を連携させてみました。
実際の開発では、サーバーサイトとクライアントサイドは緊密に連携をすることが多いと思いますので、今回のサンプルでおおまかな雰囲気を感じていただけると嬉しいです。
後は、同じデータを複数回使う、また、パラメータで内容を可変にする場合はAjax
でデータ取得すると後々の開発も楽になると思います。
ぜひ皆さんもやってみてくださいね。
ではでは〜
「空気清浄機ってこんなに
いいもんだったとは」