Chuyển đến nội dung chính

Bài 18: Inertia.js & Vue/React Integration

Inertia.js monolith architecture. Laravel + Vue/React SPA. Shared data, form helpers, file uploads. Server-side rendering. Inertia vs Livewire vs traditional SPA.

💻 Lập trình — Bài 18 Bài 18: Inertia.js & Vue/React Integration

Laravel: Từ Cơ bản đến Nâng cao

Phần 5: Modern Full-Stack

xdev.asia

1. Inertia.js Setup

composer require inertiajs/inertia-laravel
npm install @inertiajs/vue3
// Controller — trả về Inertia response
use Inertia\Inertia;

class ProductController extends Controller
{
    public function index()
    {
        return Inertia::render('Products/Index', [
            'products' => Product::with('category')->paginate(20),
            'filters' => request()->only(['search', 'category']),
        ]);
    }

    public function store(StoreProductRequest $request)
    {
        Product::create($request->validated());
        return redirect()->route('products.index')
            ->with('success', 'Sản phẩm đã được tạo!');
    }
}

2. Vue Pages

<!-- resources/js/Pages/Products/Index.vue -->
<script setup>
import { Head, Link, router } from '@inertiajs/vue3';
import { ref, watch } from 'vue';

const props = defineProps({
    products: Object,
    filters: Object,
});

const search = ref(props.filters.search ?? '');

watch(search, (value) => {
    router.get('/products', { search: value }, {
        preserveState: true,
        replace: true,
    });
});
</script>

<template>
    <Head title="Sản phẩm" />
    <input v-model="search" placeholder="Tìm kiếm..." />
    <div v-for="product in products.data" :key="product.id">
        <Link :href="`/products/${product.slug}`">
            {{ product.name }} - {{ product.price }}đ
        </Link>
    </div>
</template>

3. Inertia Forms

<script setup>
import { useForm } from '@inertiajs/vue3';

const form = useForm({
    name: '',
    price: 0,
    description: '',
    image: null,
});

function submit() {
    form.post('/products', {
        forceFormData: true,
        onSuccess: () => form.reset(),
    });
}
</script>

<template>
    <form @submit.prevent="submit">
        <input v-model="form.name" />
        <span v-if="form.errors.name">{{ form.errors.name }}</span>
        <button :disabled="form.processing">Lưu</button>
    </form>
</template>

4. Shared Data

// Middleware HandleInertiaRequests
public function share(Request $request): array
{
    return [
        ...parent::share($request),
        'auth' => ['user' => $request->user()],
        'flash' => ['success' => $request->session()->get('success')],
    ];
}

5. Livewire vs Inertia

Tính năngLivewireInertia
FrontendBlade + Alpine.jsVue/React
SPA FeelTốtRất tốt
Learning curveThấpTrung bình
JS ecosystemHạn chếĐầy đủ
SSRTự độngCần setup

Bài tiếp theo: Testing trong Laravel.