Xây dựng SPA với Laravel Inertia và Vue.js

· 3 min read

"Modern Monolith" đang trỗi dậy. Các developer mệt mỏi với việc quản lý hai repository riêng biệt (backend API + frontend SPA), xử lý JWT tokens, và duplicate logic validation.

Đây là lúc Inertia.js xuất hiện.

Inertia là gì?

Inertia không phải là framework; nó là lớp keo kết nối server-side framework của bạn (Laravel) với client-side framework (Vue, React, Svelte).

Nó cho phép bạn xây dựng Single Page Application (SPA) như thể nó là một multi-page app truyền thống.

  • Không cần client-side routing (Vue Router).
  • Không cần API.
  • Controllers trả về Inertia::render thay vì view().

Cài đặt

Đầu tiên, cài đặt server-side adapter:

composer require inertiajs/inertia-laravel

Client-side (Vue 3):

npm install @inertiajs/vue3

Quy trình làm việc

1. Route (web.php) Routing Laravel chuẩn. Không cần API routes.

Route::get('/users', [UserController::class, 'index']);

2. Controller Thay vì trả về JSON hoặc Blade view, trả về Inertia response.

use Inertia\Inertia;

public function index()
{
    return Inertia::render('Users/Index', [
        'users' => User::all()->map(fn($user) => [
            'id' => $user->id,
            'name' => $user->name,
            'edit_url' => route('users.edit', $user),
        ]),
    ]);
}

3. Page (resources/js/Pages/Users/Index.vue) Nhận data dưới dạng props.

<script setup>
defineProps({ users: Array })
</script>

<template>
  <Layout>
    <h1>Users</h1>
    <div v-for="user in users" :key="user.id">
      {{ user.name }}
      <Link :href="user.edit_url">Edit</Link>
    </div>
  </Layout>
</template>

Shared Data và Flash Messages

Một trong những siêu năng lực của Inertia là middleware HandleInertiaRequests. Bạn có thể chia sẻ data globally, như authenticated user hoặc flash messages.

public function share(Request $request): array
{
    return array_merge(parent::share($request), [
        'auth' => [
            'user' => $request->user(),
        ],
        'flash' => [
            'message' => fn () => $request->session()->get('message')
        ],
    ]);
}

Forms dễ dàng

Inertia đi kèm với form helper xử lý submission, loading states và validation errors tự động.

import { useForm } from '@inertiajs/vue3'

const form = useForm({
  email: null,
  password: null,
})

function submit() {
  form.post('/login')
}

Nếu validation thất bại trên server, Laravel redirect về với errors. Inertia chặn điều này và điền vào form.errors. Không cần try/catch blocks!

Kết luận

Inertia mang đến điều tốt nhất của cả hai thế giới: trải nghiệm developer của Laravel + Blade, và trải nghiệm người dùng của một SPA nhanh nhạy. Nếu bạn không cần mobile app API ngay lập tức, Inertia thường là lựa chọn thông minh nhất.

Bình luận