基於 Laravel + Inertia.js + Vue 的專案

專案需求

  • 實現 SPA 體驗
  • 自行客製化後台介面
  • 保留 Laravel Controller + Blade routing 的開發體驗,畫面使用 Vue 呈現

開發起手式

1. 建立 Laravel 專案

composer create-project --prefer-dist laravel/laravel project-name "10.*"

--prefer-dist:優先從 Laravel 的發佈包中安裝,而不是從 Git 儲存庫拉取,速度較快且為穩定版本。


2. 安裝 Laravel Breeze(Inertia + Vue)

composer require laravel/breeze --dev

# 安裝 Breeze Vue preset,會自動安裝 inertiajs/inertia-laravel
php artisan breeze:install vue

若因環境問題 inertiajs/inertia-laravel 沒有安裝,可手動補上:

composer require inertiajs/inertia-laravel

Breeze 安裝完成後,會設定好 Vue 3、Vite、自動建立 Vue 頁面及 layout 等預設檔案。


3. 安裝前端依賴與初始化

npm install
php artisan key:generate
php artisan migrate

4. 調整 Vite 設定(可選)

若專案使用 Apache 並設定了 VirtualHost,可設定 Vite 開發伺服器使用固定 host 名稱,避免 HMR 問題。

vite.config.js

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

export default defineConfig({
    server: {
        host: 'domainName', // 對應 .env 的 APP_URL 網域
        port: 5173,
        strictPort: true,
    },
    plugins: [
        laravel({
            input: 'resources/js/app.js',
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
});

5. 調整 .env

APP_URL=url
VITE_DEV_SERVER_URL=url:5173

使用方式

路由設定

routes/web.php

use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\RedirectResponse;
use App\Http\Controllers\DashboardController;
use App\Http\Controllers\ProfileController;

// 首頁導向登入或儀表板
Route::get('/', function (): RedirectResponse {
    return Auth::check()
        ? redirect()->route('dashboard')
        : redirect()->route('login');
});

// 需驗證登入後才能進入儀表板
Route::middleware(['auth', 'verified'])->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
});

// 個人資料頁面
Route::middleware('auth')->group(function () {
    Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
    Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
    Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
});

// Breeze 預設包含的 auth 路由
require __DIR__.'/auth.php';

控制器

app/Http/Controllers/DashboardController.php

namespace App\Http\Controllers;

use Inertia\Inertia;

class DashboardController extends Controller
{
    public function index()
    {
        return Inertia::render('Dashboard', [
            'title' => '儀表板',
        ]);
    }
}

Vue 頁面元件

resources/js/Pages/Dashboard.vue

<script setup>
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import { Head } from '@inertiajs/vue3';

defineProps({
    title: String,
});
</script>

<template>
    <Head :title="title" />

    <AuthenticatedLayout>
        <template #header>
            <h2 class="font-semibold text-xl text-gray-800 leading-tight">{{ title }}</h2>
        </template>

        <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">You're logged in!</div>
                </div>
            </div>
        </div>
    </AuthenticatedLayout>
</template>

其他建議

  • 若需啟用 TypeScript,Breeze 安裝後可直接執行 php artisan breeze:install vue --typescript
  • 若日後需支援 SSR,請使用 Inertia SSR 指南