логотип PurpleSchool
логотип PurpleSchool

5 правил использования Inertia с Vue и Laravel

Автор

Олег Марков

Введение

Когда вы соединяете Laravel и Vue с помощью Inertia, вы получаете мощный инструмент для построения современных одностраничных приложений (SPA), избавляясь от многих классических проблем интеграции backend и frontend. Inertia позволяет использовать Laravel для серверной логики и рендера, а Vue — для интерфейса, предоставляя ощущение работы нативного SPA, без необходимости создавать REST или GraphQL API.

Сегодня я хочу поделиться с вами 5 основными правилами работы с Inertia, которые сделают ваш опыт проще, а проекты — надёжнее и легче поддерживаемыми. Каждый пункт я сопроводил примерами и объяснениями, чтобы вы могли сразу применить полученные знания на практике. По пути мы разберём архитектуру Inertia, структуру рендеринга, передачу данных, работу со стейтом и роутингом, уделяя внимание тонкостям, которые часто упускают новички.


1. Строим архитектуру: Разделяйте зоны ответственности

Грамотное разделение backend и frontend при работе с Inertia — основа вашего успеха. Важно сохранять логику бизнес-процессов и работы с данными на стороне Laravel, а отображение и обработку пользовательских интеракций — во Vue.

Почему это важно

Если смешивать логику обработки данных и отображения, ваш код быстро потеряет структурность и будет сложно поддаваться поддержке. Inertia помогает избежать дублирования методов между backend и frontend, но за архитектуру отвечаете вы.

Как это реализовать

Рассмотрим типичный маршрут:

// web.php в Laravel
use Inertia\Inertia;

Route::get('/dashboard', function () {
    // Получаем данные на сервере
    $users = User::all();

    // Рендерим Vue-компонент через Inertia, передаём данные
    return Inertia::render('Dashboard', [
        'users' => $users // Данные отправляются во Vue
    ]);
});

Смотрите, в этом примере весь сбор данных происходит на стороне Laravel, а компонент Vue просто отображает их так, как нужно:

<!-- resources/js/Pages/Dashboard.vue -->
<template>
  <div>
    <h1>Пользователи</h1>
    <ul>
      <li v-for="user in users" :key="user.id">{{ user.name }}</li>
    </ul>
  </div>
</template>

<script setup>
import { defineProps } from 'vue'

// Здесь мы объявляем, что наш компонент ожидает проп 'users'
const props = defineProps(['users'])
</script>

Здесь Dashboard.vue ничего не знает о том, как были получены данные — он просто их рисует. Это упрощает сопровождение и вызывает меньше багов при масштабировании.


2. Передавайте только нужные данные

Не отправляйте во Vue больше информации, чем необходимо для отображения. Лучше собрать сразу всё, что требуется для одной страницы, чем устраивать дополнительные запросы или перегружать клиент избыточным payload.

Теория

В Inertia принцип "page props" означает, что все данные должны передаваться одной порцией при рендере страницы. Он похож на подход SSR (server-side rendering), но с сохранением SPA-ощущения.

На практике

Если ваша страница ожидает только имена и email пользователей, не отправляйте всю модель User:

// Вместо этого:
return Inertia::render('Dashboard', [
    'users' => User::select('id', 'name', 'email')->get()
]);

Это минимизирует объём данных, передаваемых клиенту, а значит, ускоряет загрузку страницы и защищает от случайного раскрытия лишней информации.

Сериализация данных

Обратите внимание: когда вы передаёте Eloquent-коллекции или модели, Laravel автоматически их сериализует в массивы. Если нужно управление этим процессом — используйте ресурсы:

return Inertia::render('Dashboard', [
    'users' => UserResource::collection(User::all())
]);

UserResource позволяет чётко указать, какие атрибуты попадут во Vue:

// app/Http/Resources/UserResource.php
public function toArray($request)
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        // email и другие поля...
    ];
}

3. Используйте Inertia формирование ответов для унификации возврата

Inertia предлагает простые методы для формирования "SPA-like" ответов — используйте их всегда, когда работаете с переходами и формами. Это поможет унифицировать обработку событий (например, валидации ошибок или flash-сообщений).

Обработка форм и ошибок

Давайте рассмотрим, как корректно возвращать ошибки валидации:

use Illuminate\Http\Request;
use Inertia\Inertia;

public function store(Request $request)
{
    $request->validate([
        'title' => 'required|max:255',
    ]);

    // ...сохраняем данные...

    return redirect()->route('posts.index')->with('success', 'Пост добавлен!');
}

Во Vue компоненте можно отловить ошибки, так как Inertia передаст их через пропс errors:

<template>
  <form @submit.prevent="submit">
    <input v-model="form.title" />
    <span v-if="errors.title">{{ errors.title }}</span>
    <button type="submit">Создать</button>
  </form>
</template>

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

const form = useForm({ title: '' })
const errors = form.errors

function submit() {
  form.post('/posts')
}
</script>

Flash-сообщения

Вы также можете централизованно передавать flash-сообщения с сервера:

return redirect()->route('dashboard')->with('message', 'Вы успешно добавили пользователя!');

В Vue компонент всплывающее сообщение может брать из пропсов:

<template>
  <div v-if="message" class="flash">{{ message }}</div>
</template>

<script setup>
import { defineProps } from 'vue'
const props = defineProps(['message'])
</script>

Очень важно использовать компонент <Link> от Inertia для перехода между страницами, чтобы не было полного перезагрузки — это избавляет от потери состояния SPA.

Если вы воспользуетесь стандартным тегом <a>, то браузер полностью перезагрузит страницу. Используйте компонент Inertia для плавных переходов:

<template>
  <Link href="/dashboard" class="nav-link">Перейти в Дашборд</Link>
</template>

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

Вот простой пример меню:

<template>
  <nav>
    <Link href="/profile">Профиль</Link>
    <Link href="/settings">Настройки</Link>
  </nav>
</template>

Этот подход сохраняет стейт вашего приложения, не выбрасывает пользователя из SPA "режима" и делает всё заметно быстрее, чем обычные переходы.

Передача данных с переходом

Можете передавать параметры через href:

<Link :href="`/users/${user.id}/edit`">Редактировать</Link>

5. Не забывайте про "shared" данные

Иногда есть смысл сделать часть пропсов доступными на всех страницах — например, данные авторизации или flash-сообщения. Используйте Inertia::share для этого.

Как это сделать

В файле AppServiceProvider.php или отдельном сервис-провайдере создайте метод, который добавит данные "по умолчанию" ко всем ответам Inertia.

// app/Providers/AppServiceProvider.php
use Inertia\Inertia;
use Illuminate\Support\Facades\Auth;

public function boot()
{
    Inertia::share([
        // Данные текущего пользователя
        'auth' => fn () => [
            'user' => Auth::user()
        ],
        // flash-сообщение
        'flash' => fn () => session('message')
    ]);
}

Теперь в любом компоненте Vue у вас будет доступ к этим prop'ам:

<template>
  <div>
    <span v-if="auth.user">Добро пожаловать, {{ auth.user.name }}</span>
    <div v-if="flash">{{ flash }}</div>
  </div>
</template>

<script setup>
import { defineProps } from 'vue'
// auth и flash приходят теперь на все страницы
const props = defineProps(['auth', 'flash'])
</script>

Это избавляет вас от необходимости явно прокидывать часто используемые данные в каждый отдельный рендер страницы.


Заключение

Работая с Inertia и используя Laravel и Vue, вы сочетаете лучшее из двух миров: мощный backend и современный реактивный frontend. Ключевые правила — это держать архитектуру чистой, минимизировать объём передаваемой информации, централизовать обработку ошибок и flash-сообщений, использовать Inertia Links для роутинга и делиться общими данными корректно через Inertia::share.

Если вы ещё не использовали Inertia в связке с Laravel и Vue — эти правила помогут встроить его в ваш процесс разработки и раскрыть его для себя по-настоящему эффективно.


Частозадаваемые технические вопросы по теме статьи и ответы на них

Как правильно использовать middleware с Inertia страницами?

Вы можете использовать все стандартные middleware Laravel, включая аутентификацию, проверки ролей и прочее. Для ограничения доступа к странице — просто применяйте middleware как обычно:

Route::get('/dashboard', function () {
    // ...
})->middleware('auth');

Inertia автоматически учтёт редирект или 403/401 ответ. Для кастомной обработки неавторизованных ошибок используйте свой обработчик исключений.


Как реализовать lazy-загрузку данных на стороне клиента?

Если не хотите передавать все данные сразу, возвращайте минимальный набор, а затем используйте API-запросы (например, через Axios или Fetch) внутри Vue-компонентов для подгрузки остальных данных по требованию.


Как реализовать динамические параметры роутинга?

В Laravel определяйте маршрут с параметром, например:

Route::get('/users/{user}', function (User $user) {
    return Inertia::render('UserProfile', ['user' => $user]);
});

Во Vue получение пропсов идентично другим страницам.


Можно ли использовать Vue Router совместно с Inertia?

Использовать Vue Router не рекомендуется — стандарный роутинг и управление историей берёт на себя Inertia (он использует History API). Если вы попытаетесь внедрять Vue Router, скорее всего получите конфликты с навигацией.


Как загрузить внешние библиотеки или плагины во Vue при использовании Inertia?

В main.js вашего Vue-приложения импортируйте сторонние библиотеки или плагины так же, как и в обычном SPA:

import { createApp, h } from 'vue'
import SomePlugin from 'some-plugin'
import { createInertiaApp } from '@inertiajs/vue3'

createInertiaApp({
  // ... ваши настройки,
  setup({ el, App, props, plugin }) {
    const vueApp = createApp({ render: () => h(App, props) })
    vueApp.use(plugin)
    vueApp.use(SomePlugin)
    vueApp.mount(el)
  }
})

Это работает как обычно в Vue 3, совместимо с Inertia.

Стрелочка влевоПолный гайд по компоненту messages во VuejsРабота с модулями и пакетами в VueСтрелочка вправо

Все гайды по Vue

Руководство по валидации форм во Vue.jsИнтеграция Tiptap для создания редакторов на VueРабота с таблицами во Vue через TanStackИнструкция по установке и компонентам Vue sliderУправление пакетами Vue js с помощью npmУправление пакетами и node modules в Vue проектахКак использовать meta для улучшения SEO на VueПолный гайд по компоненту messages во Vuejs5 правил использования Inertia с Vue и LaravelРабота с модулями и пакетами в VueИнструкция по работе с grid на VueGithub для Vue проектов - подробная инструкция по хранению и совместной работеНастройка ESLint для Vue проектов и поддержка качества кодаОбработка ошибок и отладка в Vue.jsИспользование Vue Devtools для отладки и мониторинга приложенийРабота с конфигурационными файлами и скриптами VueСоздание и настройка проектов Vue с помощью Vue CLI3 способа интеграции Chart.js с Vue для создания графиковРабота с Canvas во VueИнструкция по реализации календаря во VueРабота с Ant Design Vue для создания UI на Vue
Веб приложения на Vue архитектура и лучшие практикиИспользование Vite для быстрого старта и сборки проектов на Vue 3Работа с URL и ссылками в приложениях на VueРабота с пользовательскими интерфейсами и UI библиотеками во VueОрганизация и структура исходных файлов в проектах VueИспользование Quasar Framework для разработки на Vue с готовыми UI-компонентамиОбзор популярных шаблонов и стартовых проектов на VueИнтеграция Vue с PHP для создания динамичных веб-приложенийКак организовать страницы и маршруты в проекте на VueNuxt JS и Vue 3 для SSR приложенийСоздание серверных приложений на Vue с помощью Nuxt jsИспользование Vue Native для разработки мобильных приложенийОрганизация и управление индексной страницей в проектах VueИспользование Docker для контейнеризации приложений на VueИнтеграция Vue.js с Django для создания полноценных веб-приложенийСоздание и работа с дистрибутивом build dist Vue приложенийРабота со стилями и CSS в Vue js для красивых интерфейсовСоздание и структурирование Vue.js приложенияКак исправить ошибку cannot find module vueНастройка и сборка проектов Vue с использованием современных инструментовИнтеграция Vue с Bitrix для корпоративных решенийРазработка административных панелей на Vue js
Обзор и использование утилит Vue для удобной разработкиРабота с обновлениями компонента и жизненным циклом updateРазрешение конфликтов и ошибок с помощью Vue resolveИспользование query-параметров и их обработка в маршрутах VueЗагрузка и управление состоянием загрузки в VueИспользование библиотек Vue для расширения функционалаРабота с JSON данными в приложениях VueКак работать с экземплярами компонента Instance во VueПолучение данных и API-запросы во Vue.jsЭкспорт и импорт данных и компонентов в VueОбработка событий и их передача между компонентами VuejsГайд по defineEmits на Vue 3Понимание core функционала Vue и его применениеПонимание и применение Composition API в Vue 3Понимание и работа с компилятором VueКогда и как использовать $emit и call во VueВзаимодействие с внешними API через Axios в Vue
5 библиотек для создания tree view во VueИнтеграция Tailwind CSS с Vue для современных интерфейсовИнтеграция Vue с серверной частью и HTTPS настройкамиКак обрабатывать async операции с Promise во VueИнтеграция Node.js и Vue.js для разработки приложенийРуководство по интеграции Vue js в NET проектыПримеры использования JSX во VueГайд по импорту и регистрации компонентов на VueМногоязычные приложения на Vue с i18nИнтеграция FLIR данных с Vue5 примеров использования filter во Vue для упрощения разработки3 примера реализации drag-and-drop во Vue
Управление переменными и реактивными свойствами во VueИспользование v for и slot в VueПрименение v-bind для динамической привязки атрибутов в VueУправление пользователями и их данными в Vue приложенияхСоздание и использование UI Kit для Vue приложенийТипизация и использование TypeScript в VuejsИспользование шаблонов в Vue js для построения интерфейсовИспользование Swiper для создания слайдеров в VueРабота со стилями и стилизацией в VueСтруктура и особенности Single File Components SFC в VueРабота со SCSS в проектах на Vue для стилизацииРабота со скроллингом и прокруткой в Vue приложенияхПрименение script setup синтаксиса в Vue 3 для упрощения компонентовИспользование scoped стилей для изоляции CSS в компонентах Vue3 способа улучшить навигацию Vue с push()Обработка запросов и асинхронных операций в VueПонимание и использование provide inject для передачи данных между компонентамиПередача и использование props в Vue 3 для взаимодействия компонентовПередача данных между компонентами с помощью props в Vue jsУправление property и функциями во Vue.jsРабота со свойствами компонентов VueУправление параметрами и динамическими данными во VueРабота с lifecycle-хуком onMounted во VueОсновы работы с объектами в VueПонимание жизненного цикла компонента Vue js на примере mountedИспользование модальных окон modal в Vue приложенияхИспользование методов в компонентах Vue для обработки логикиИспользование метода map в Vue для обработки массивовИспользование хуков жизненного цикла Vue для управления состоянием компонентаРабота с ключами key в списках и компонентах VueОбработка пользовательского ввода в Vue.jsРабота с изображениями и их оптимизация в VueИспользование хуков жизненного цикла в VueОрганизация сеток и гридов для верстки интерфейсов на VueСоздание и управление формами в VueОрганизация файлов и структура проекта Vue.jsКомпоненты Vue создание передача данных события и emitРабота с динамическими компонентами и данными в Vue3 способа манипулирования DOM на VueРуководство по div во VueИспользование директив в Vue и их расширенные возможностиОсновы и применение директив в VueИспользование директив и их особенности на Vue с помощью defineИспользование компонентов datepicker в Vue для выбора датОрганизация циклов и итераций во VueКак работает компиляция Vue CoreСоздание и использование компонентов в Vue JSОбработка кликов и пользовательских событий в VueИспользование классов в Vue для организации кода и компонентовИспользование директивы checked для управления состоянием чекбоксов в VueГайд на checkbox компонент во VueОтображение данных в виде графиков с помощью Vue ChartСоздание и настройка кнопок в VueСоздание и настройка кнопок в Vue приложенияхРабота с lifecycle-хуками beforeCreate и beforeMount во VueИспользование массивов и методов их обработки в VueИспользование массивов и их обработка в Vue
Использование Vuetify для создания современных интерфейсов на VueИспользование transition во VueТестирование компонентов и приложений на VueРабота с teleport для управления DOM во VueПять шагов по настройке SSR в VuejsИспользование Shadcn UI компонентов с Vue для продвинутых интерфейсовИспользование router-link для навигации в Vue RouterКак использовать require в Vue для динамического импорта модулейРабота с динамическим рендерингом и виртуальным DOM на Vue.jsИспользование ref для управления ссылками и реактивностью в Vue 3Использование Vue Pro и его преимущества для профессиональной разработкиРуководство по nextTick для работы с DOMСоздание и использование компонентов с помощью Vue js и CУправление состоянием и реактивностью через inject и provideДинамическое обновление компонентов и данных на VueГлубокое изучение документации Vue и как эффективно её использоватьИспользование Crystal с Vue для разработкиИспользование вычисляемых свойств для динамического отображения данных на Vue jsОптимизация производительности и предупреждения в Vue
Открыть базу знаний