51.

Laravel + Vue.js 連携完全ガイド (Vite / Inertia / SPA)

編集
この記事の要点
  • Laravel + Vue 連携パターン 4 つ: ① Blade 内で Vue マウント ② Inertia.js (SPA 風) ③ API + Vue SPA 分離 ④ Nuxt SSR + Laravel API
  • Laravel 9.x 以降は Laravel Mix → Vite が公式デフォルト
  • Blade から Vue へのデータ受け渡しは :user="{{ json_encode($user) }}" または data-* 属性
  • Inertia.jsBlade 不使用 + Vue/React コンポーネント + Laravel ルーティング のハイブリッド (Laravel Jetstream / Breeze で対応)
  • API 分離型は Sanctum (SPA 認証) + axios + Pinia が定番

連携パターンの選択

パターン特徴向いている用途
① Blade + Vue 部分導入Blade に を埋め込み既存 Laravel への段階導入
② Inertia.jsVue でビュー、Laravel ルーティング維持SPA UX が欲しいが認証は Laravel
③ API + Vue SPA 分離Laravel = JSON API のみ、Vue = 別プロジェクトモバイル併用 / フロント独立
④ Nuxt + Laravel APINuxt で SSR、Laravel で APISEO 重要 / SSR 必要

パターン1: Blade + Vue 部分導入 (Vite)

Laravel 9.x 以降のデフォルト構成。vite.config.js + resources/js/app.js で Vue 3 をマウントします。

# Laravel 新規プロジェクト
composer create-project laravel/laravel my-app
cd my-app

# Vue 3 と Vite プラグインを追加
npm install vue@3 @vitejs/plugin-vue
// 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,
        },
      },
    }),
  ],
});
// resources/js/app.js
import './bootstrap';
import { createApp } from 'vue';
import HelloWorld from './components/HelloWorld.vue';

const app = createApp({});
app.component('hello-world', HelloWorld);
app.mount('#app');
{{-- resources/views/welcome.blade.php --}}



  @vite(['resources/css/app.css', 'resources/js/app.js'])


  
{{-- Laravel から Vue へ props 渡し --}}



# 開発サーバ起動 (HMR 付き)
npm run dev

# 本番ビルド
npm run build
# → public/build/ に出力

パターン2: Inertia.js (SPA 風)

Blade を捨てて Vue でビューを書きながら、ルーティング / 認証 / バリデーションは Laravel に任せる。Jetstream / Breeze のオプションで導入できます。

# Breeze + Inertia + Vue
composer require laravel/breeze --dev
php artisan breeze:install vue
npm install
npm run dev
// routes/web.php
use Inertia\Inertia;
use App\Models\Post;

Route::get('/posts', function () {
    return Inertia::render('Posts/Index', [
        'posts' => Post::latest()->get(),
    ]);
});

// または Controller
public function index() {
    return Inertia::render('Posts/Index', [
        'posts' => Post::latest()->paginate(20),
        'filters' => request()->only(['search']),
    ]);
}



パターン3: API + Vue SPA 完全分離

Laravel をバックエンド API のみとして使い、Vue は別ディレクトリ / 別サーバで動かします。認証は Laravel Sanctum が定番。

# Laravel 側
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

# .env
SANCTUM_STATEFUL_DOMAINS=localhost:5173
SESSION_DOMAIN=.example.test

# Vue 側 (別プロジェクト)
npm create vue@latest my-spa
cd my-spa
npm install axios pinia vue-router
// routes/api.php
use App\Http\Controllers\Api\PostController;

Route::middleware('auth:sanctum')->group(function () {
    Route::apiResource('posts', PostController::class);
    Route::get('/user', fn() => auth()->user());
});
// src/api.js (Vue 側)
import axios from 'axios';

const api = axios.create({
  baseURL: 'http://api.example.test',
  withCredentials: true,   // ★ Sanctum クッキー認証
  headers: { 'Accept': 'application/json' },
});

// ログイン
export async function login(email, password) {
  // 1. CSRF クッキー取得
  await api.get('/sanctum/csrf-cookie');
  // 2. ログイン
  await api.post('/login', { email, password });
}

// 記事一覧取得
export async function fetchPosts() {
  const { data } = await api.get('/api/posts');
  return data;
}

パターン4: Nuxt 3 + Laravel API (SSR)

# Nuxt 3 プロジェクト作成
npx nuxi@latest init my-nuxt
cd my-nuxt
npm install
npm run dev   # http://localhost:3000

# .env
NUXT_PUBLIC_API_BASE=http://api.example.test



Laravel Mix から Vite への移行

古い Laravel (8.x 以前) は webpack.mix.js を使っていました。新規は Vite に移行してください:

# Mix を削除
npm uninstall laravel-mix
rm webpack.mix.js

# Vite を導入
npm install -D vite laravel-vite-plugin @vitejs/plugin-vue
# vite.config.js を作成 (前述参照)

# Blade テンプレートを書き換え
# 旧: 
# 新: @vite(['resources/css/app.css', 'resources/js/app.js'])

# 起動
npm run dev

FAQ

Q: Inertia と API + Vue SPA、どちらを選ぶ?
A: Laravel チームで Vue を書きたい → Inertia。フロントとバックを別チームで分けたい → API 分離。

Q: Vue から CSRF トークンを送る
A: Laravel Sanctum なら /sanctum/csrf-cookie で自動。Blade 内 Vue は を axios のヘッダにセット。

Q: TypeScript 対応は?
A: Vite + Vue 3 で npm install -D typescript vue-tsctsconfig.json 配置。Inertia + TS も Breeze で選択可。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. インストールと設定
  2. クイックスタート & チュートリアル(初心者向け)
  3. クイックスタート & チュートリアル(中級者向け)
  4. ルーティング
  5. Bladeテンプレート(ビュー/レイアウト)
  6. コントローラー
  7. マイグレーションとテーブル定義
  8. データベースの設定
  9. Eloquentモデル (ORM)
  10. SQLとクエリビルダー
  11. バリデーション
  12. .envファイルの設定値へのアクセス
  13. 動作環境による分岐処理
  14. configフォルダ配下の設定値へのアクセス
  15. assetヘルパーを利用したpublicフォルダへのアクセス
  16. storageフォルダへのアクセス
  17. アプリケーション名の変更
  18. メンテナンス
  19. ログイン画面(認証システム)の作成
  20. ログインの必須化
  21. ログインユーザー情報の取得
  22. ルートの認証化
  23. 本番サーバーへのデプロイ方法
  24. 多言語化
  25. csrf_field
  26. ファイルのダウンロード
  27. CSVのアップロードおよび読み込み(maatwebsite/excel)
  28. ページタイトルの設定
  29. コマンド一覧
  30. エラー一覧
  31. SQLの実行ログ出力方法
  32. キャッシュのクリア
  33. Selectの結果の最初もしくは最後に任意の値を追加する方法
  34. ajaxでPOST通信する際の注意点
  35. ソーシャルログインの実装
  36. セッション情報の確認
  37. ログイン、ユーザー登録、パスワードリセット後のリダイレクト先の変更方法
  38. redirectやreturn viewにメッセージを付与する方法
  39. クッキー(cookie)の設定と取得
  40. クラスの再読み込み
  41. csrfの有効時間を変更する方法
  42. ViewComposerを用いてviewに共通の値を付与する方法
  43. View::shareを用いて共通の値を各ビューに渡す方法
  44. ミドルウェアを用いた処理の共通化
  45. Middleware内でAuth::check()などを使用する方法
  46. Controller以外でリダイレクトする方法
  47. セッションの値の取得/保存/更新/削除
  48. $requestの値を変更する方法
  49. 常時SSL化
  50. ページング(ページネーション)をする方法
  51. vue.jsとの連携
  52. Vue.jsと連携するSPA実行環境構築
  53. .envの値をvue.jsで参照する方法
  54. vue.jsを本番環境にリリースする方法
  55. could not find driver(Windows, MySQL編)