書籍「Laravelの教科書」Laravel13対応サポートガイド公開中 → ダウンロードはこちら

Laravel11とVue3の連携方法:カウンタを作ってみる

LaravelとVue連携

Laravel11とVue3の連携方法を解説します。

LaravelとVueを連携させたいときに、参考にしてください♪

Laravel11とVue3の連携方法:カウンタを作ってみる

まずは、Laravelのプロジェクトを作成します。

Laravelプロジェクト作成&Breeze認証インストール

Laravelのプロジェクト作成方法は色々ありますが、今回はxampp(ザンプ)を使いました。

下記コマンドでプロジェクトを作ります。

composer create-project --prefer-dist laravel/laravel vuetest

cdコマンドでvuetestに移動します。Breezeライブラリをインストールします。

composer require laravel/breeze --dev
php artisan breeze:install

データベースの作成と設定も必要です。

インストールやデータベース作成について、詳細は下記ご覧ください。

プラグインのインストール

次に下記コマンドを実行して、プラグインをインストールします。

npm install --save-dev @vitejs/plugin-vue

vite.config.jsの変更

vite.config.jsファイルに、下記のようにコードを追加します。

【vite.config.js】

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
// 追加
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/css/app.css',
                'resources/js/app.js',
            ],
            refresh: true,
        }),
        // 追加
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
   // 追加
    resolve: { 
        alias: {
            vue: 'vue/dist/vue.esm-bundler.js',
        },
    },
});

Vueのエイリアスを vue/dist/vue.esm-bundler.js に設定することで、開発時にVueのテンプレートをリアルタイムでコンパイルできます。

Vueファイルの作成

resources/jsの中に、componentsを作り、その中に、TestComponent.vueファイルを作ります。下記のコードをいれます。今回は従来のOptions APIでコードを書きました。

【TestComponent.vue】

<template>
  <button v-on:click="counter" class="btn">数字:{{count}}</button>
</template>


<script>
export default {
  data() {
    return {
      count: 1
    }
  },
  methods: {
    counter() {
      this.count++;
    }
  }
}
</script>
<style scoped>
.btn {
    background-color: blue;
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 5px;
}
</style>

app.jsの変更

resoures/js/app.jsの中に、下記のコードを追加します。

【app.js】

// 追加
import { createApp } from 'vue';
import TestComponent from './components/TestComponent.vue';

const app = createApp({});
app.component('test-component', TestComponent);
app.mount('#app');

app id属性の設定

resources/views/layouts/app.blade.phpの中のbody開始タグの中に、id=”app”を追加します。

【app.blade.php】

    </head>
    <body class="font-sans antialiased" id="app">
        <div class="min-h-screen bg-gray-100">

Vueファイル埋め込みの設定

作成したビューファイルは、ダッシュボードファイルの中に埋め込みます。resources/views/dashboard.blade.phpの中に、<test-component></test-component>コードを追加します。

【dashboard.blade.php】

<x-app-layout>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            {{ __('Dashboard') }}
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
            <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                <div class="p-6 text-gray-900">
                    {{-- 追加 --}}
                    <test-component></test-component>
                </div>
            </div>
        </div>
    </div>
</x-app-layout>

ブラウザで確認

ブラウザで動作を確認します。まず、/registerでユーザー登録します。ログイン後のダッシュボードで、次のようにカウンタが表示されます。

ボタンをクリックすると、数字が増えていくのを確認してください。

もしロゴが大きく表示される場合には、vite.config.jsに下記を加えます。

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
// 追加
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/css/app.css',
                'resources/js/app.js',
            ],
            refresh: true,
        }),
        // 追加
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
    resolve: { 
        alias: {
            vue: 'vue/dist/vue.esm-bundler.js',
        },
    },
    // 画像が大きくなったりしたときはこちら
    server: {
        hmr: {
            host: 'localhost',
        },
    },
});

追記:Property “open” was accessed during render but is not defined on instanceエラー対策

上記の手順でコードを入力すると、コンソールに下記エラーがでます。

“Property “open” was accessed during render but is not defined on instance”
「プロパティ “open” がレンダリング中にアクセスされましたが、インスタンス上で定義されていません」

これは、body タグ内にid=”app”をいれたためです。bodyタグにid=”app”をいれると、body全体がVue.jsの管理下に入ります。

ですがLaravelには、デフォルトでlayouts/navigation.blade.php内にAlpine.jsのコードが組み込まれています。具体的には、下記コードです。

<div :class="{'block': open, 'hidden': ! open}" class="hidden sm:hidden">

このコードがVue.jsのインスタンス内で不適切に解釈され、エラーになってしまいます。

コンソールエラーを消したい場合は、今回であれば、app.blade.phpではなく、dashboard.blade.phpファイル内のdivタグの中にid=”app”を設定しましょう。

これにより、Vue.js と Alpine.js のコードが干渉せず、それぞれが独立して機能するようになります。

【dashboard.blade.php】

                    <div class="p-6 text-gray-900" id="app">
                        <test-component></test-component>
                    </div>

さいごに

以上、LaravelとVue連携について解説しました。

今回はプロジェクトの一部でVue.jsを使いました。プロジェクト全体でVueをメインに使いたい場合には、イナーシャというライブラリが便利です。

なお「Vue.jsを覚えるのは面倒」という場合には、Livewireがおすすめです。
Livewireを使うと、blade.phpファイルに記述しつつ、Vue.jsのような機能を搭載できます。ご興味あれば、Livewireの記事も見てみてください。

Vue.jsやLivewireを取り入れることで、Webアプリにインタラクティブな機能を追加できます。必要な時に、取り入れてみてくださいね。

 

LaravelとVue連携

生成AIを「安全に」使うための研修・セミナー

お問い合わせ

生成AIの業務活用で気になるのは、効率だけでなくセキュリティです。 実践的な活用に加え、セキュリティ対策もお伝えします。

詳細を見てみる
 

生成AIを「安全に」使うための研修・セミナー

お問い合わせ

生成AIの業務活用で気になるのは、効率だけでなくセキュリティです。 実践的な活用に加え、セキュリティ対策もお伝えします。

詳細を見てみる

【Laravelの教科書・プレゼント】

Junko
Laravelの使い方を覚えたい!と思ったら、ぜひ、役立ててほしいです。 基礎編は無料でプレゼント中です♪
ひつじプログラマ
会員制サイトをいちから作っていくよ。ボタンをクリックして詳細を見てね。
Laravelの教科書の詳細を見る

最新版Laravel13への対応に対応。Laravel8からの各バージョンのテキストもご覧になれます♪

【無料プレゼント】

「LaravelでWebアプリをいちから作れるようになりたい!」

そんなLaravel初心者のあなたへ【Laravelの教科書】基礎編プレゼント中! 会員制フォーラムサイトを学習しながら作れます。

詳細はこちらをクリック

最新のLaravel13に対応。Laravel8からの各バージョンのテキストもご覧になれます♪

Laravelの本を書きました。


ひつじが目印♪

Laravelの使い方を分かりやすく解説した本を書きました。 書店やAmazon等のオンラインショップにて販売中
最新版Laravel13対応用サポートガイド(PDF)あり

書籍の詳細を見てみる

Laravelの本書きました。


ひつじが目印♪
クリックするとamazonページへ。
最新版Laravel13対応用
サポートガイド(PDF)あり

書籍の詳細を見てみる
シェアする
Twitter始めました。

コメント

タイトルとURLをコピーしました