LaravelでVue.jsを使ってみる

LaravelではAuth(ユーザ認証)をインストールした時点ですでにVue.jsを利用できる状態になっているのでコンポーネントの配置やBladeテンプレートからコンポーネントへの値の渡し方をまとめておく。

開発環境

Laradock v10
Laravel 7
Vue 2.6

ExampleComponentを表示させてみる

LaravelではAuth(ユーザ認証)をインストールした時点ですでにVue.jsを利用できる状態になっています。resources/js/componentsにサンプルとしてExampleComponet.vueが用意されているので表示させてみましょう。

bladeファイル作成

タグを記述して呼び出します。

@extends('layouts.app')

@section('content')
    <example-component></example-component>
@endsection

ルーティング設定

/testにアクセスしたら先ほど作成したtest.blade.phpを表示するだけですね。

Route::get('/test', function () {
    return view('test');
});

http://localhost/test
にアクセスしたら上記で作成したtest.blade.phpが表示されるはずです。

laravel-vue1

新しいコンポーネントを作成する

新しいコンポーネントを作成した場合はタグとコンポーネントを紐づけるためにresources/js/app.jsへの登録作業が必要です。また、vue.js関連のファイルを作成や変更して場合は再コンパイルしなければなりません。

コンポーネントの作成

以下のようにExampleComponent.vueをちょっと変更してExample2Component.vueを作成してみましょう。

<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">Example2 Component</div>

                    <div class="card-body">
                        I'm an example2 component.
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

コンポーネントの登録

タグとコンポーネントの紐づけを行います。

Vue.component('example-component', require('./components/ExampleComponent.vue').default);
# 以下を追加
Vue.component('example2-component', require('./components/Example2Component.vue').default);

<example2-component>タグによってExample2Component.vueを呼び出されます。

コンポーネント呼び出し

@extends('layouts.app')

@section('content')
    <example-component></example-component>
    <example2-component></example2-component>
@endsection

再コンパイル

$ npm run dev

ここで

$ npm run watch
または
$ npm run watch-poll

とすると変更を監視して自動で反映してくれるのでこちらを使いましょう。

http://localhost/test を再読み込みしたら下図のようにExample2Componentも表示されます。

laravel-vue2

Bladeからコンポーネントに値を渡すには?

Example2Componentのcard-headerとcard-bodyの値をBladeテンプレートから変更できるようにしてみましょう。

Blade側

「data」という名前(名前は自由に設定できます)で配列をjson形式に変換してコンポーネントに渡します。

@extends('layouts.app')

@section('content')
    <example-component></example-component>
    <example2-component
        :data="{{ json_encode([
            'header' => 'This is header',
            'body' => 'This is body.',
        ]) }}"
    ></example2-component>
@endsection

プロパティ名にハイフンは使用した場合(ケバブケース)はコンポーネント側で自動的にキャメルケースに変換されるので注意が必要です。

コンポーネント側

propsで受け取ることができ、マスタッシュ構文(二重波括弧)で展開することができます。


<template>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-8">
                <div class="card">
                    <div class="card-header">{{ data.header }}</div>

                    <div class="card-body">
                        {{ data.body }}
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        // プロパティとして「data」を設定
        props: {
            data: {},
        },
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

まとめ

Vueのコンポーネントを使用するには

①コンポーネント作成
②app.jsにタグの関連付けを記述

また、Laravelからコンポーネントへの値の渡すには

①LaravelのコントローラーからBladeにデータを渡す。

// コントローラーの記述
$data = [
	'header' => 'This is header',
	'body' => 'This is body',
];
return view('test', compact('data'));

②Bladeでは使用対象のコンポーネントにプロパティとしてdataを渡す。

:data="{{ json_encode($data) }}"

複数設定できますが、Laravel側でひとつにまとめておいたほうが良さそうですね。

③コンポーネントはプロパティを設定して受け取り、マスタッシュ構文で展開する。

ちょっと面倒ですが、MPA(Multi-Page Application)としてVueを使用する場合、順番は自由ですが以上の作業が必要になるでしょう。

補足:app.jsでのコンポーネント自動登録

app.jsに記述されている以下のコメントアウトを外すと自動で紐づけしてくれるようです。

// const files = require.context('./', true, /\.vue$/i)
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))

ただし、components直下のファイルだけみたいなので、ディレクトリ分けしてるような場合は別途、状況に合わせて変更する必要がありますね。