Laravel Inertia в Laravel

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

Такая простота интеграции позволяет разработчикам использовать свои существующие навыки работы с Laravel и получать выгоду от способности Inertia модернизировать внешний интерфейс, не требуя полной реструктуризации приложения.

Использование Inertia с Laravel предлагает множество преимуществ: от преимуществ унифицированного стека до повышения эффективности, создавая более удобный и удобный для разработчиков опыт.

В этой статье мы углубимся в причины использования Inertia с Laravel, изучим его функциональность и проведем вас через процесс начала работы с Laravel Inertia.

Зачем использовать Inertia с Laravel?

Inertia.js — это мощный инструмент, который органично сочетает в себе возможности современного внешнего интерфейса с серверными платформами, такими как Laravel. Его интеграция с Laravel предлагает существенное улучшение традиционных веб-приложений, отображаемых на сервере.

Основное преимущество заключается в его способности создавать более динамичные и интерактивные пользовательские интерфейсы, сохраняя при этом надежные серверные функции, которыми славится Laravel.

Общая структура кода между внешними и внутренними операциями не только повышает производительность разработчиков, но также способствует улучшению удобства обслуживания и масштабируемости приложения.

Какую проблему решает Laravel Inertia?

Inertia с Laravel оптимизирует процесс разработки, облегчая ощущение одностраничного приложения (SPA) без полного перехода на полноценную архитектуру SPA. Это позволяет разработчикам создавать реактивные динамические интерфейсы с использованием современных интерфейсных фреймворков, таких как Vue.js или React, одновременно используя возможности серверного рендеринга Laravel.

Более того, Inertia упрощает поток данных между интерфейсом и сервером, используя контроллеры Laravel для обработки логики как внешнего, так и внутреннего интерфейса. Такая сплоченность упрощает процесс разработки, устраняя необходимость создания отдельных конечных точек API и обеспечивая более согласованную базу кода.

Как работает Inertia?

Inertia.js фундаментально меняет способ взаимодействия внешнего и внутреннего интерфейса в веб-приложении. По своей сути Inertia обеспечивает современный интерфейс, сохраняя при этом традиционную серверную архитектуру серверной части Laravel. Это достигается за счет создания моста, который плавно соединяет бэкэнд и фронтенд.

Когда пользователь взаимодействует с внешним интерфейсом, вместо традиционных полностраничных запросов Inertia использует XHR (XMLHttpRequest) или Fetch API для связи с серверной частью. Эта связь передает только основные данные, необходимые для конкретного действия.

Рабочие механизмы

  • По щелчку пользователя интерфейсная часть отправляет запрос на сервер, используя этот механизм, запуская соответствующий метод контроллера Laravel.
  • Контроллер обрабатывает запрос и возвращает ответ Inertia, включающий необходимые данные для обновления страницы без полной перезагрузки.
  • Клиент Inertia на внешнем интерфейсе получает этот ответ, использует данные для обновления содержимого страницы и плавно изменяет пользовательский интерфейс на основе полученной информации.

Проще говоря, так работает инерция.

Зачем использовать одностраничное приложение (SPA)?

Inertia с архитектурой одностраничного приложения (SPA) предлагает мощную комбинацию, которая использует сильные стороны обоих подходов.

SPA по своей конструкции обеспечивают высокую скорость отклика и гибкий пользовательский интерфейс, загружая одну HTML-страницу и затем динамически обновляя ее содержимое по мере взаимодействия пользователей с приложением.

  • Улучшенный пользовательский интерфейс. SPA превосходно обеспечивают бесперебойную работу, подобную приложениям, сокращая перезагрузку страниц и динамическую доставку контента. Inertia дополняет это, позволяя SPA поддерживать высокий уровень интерактивности, одновременно извлекая выгоду из внутренней структуры Laravel.
  • Упрощенная разработка: объединение Inertia с SPA снижает сложность управления внешней маршрутизацией, состоянием и интеграцией API. Подход Inertia позволяет разработчикам использовать возможности SPA, сохраняя при этом простоту взаимодействия между серверной и внешней частью.

Последовательный рабочий процесс разработки: Inertia поддерживает рабочий процесс, соответствующий структуре Laravel, что облегчает разработчикам, уже знакомым с Laravel, переход к более современному подходу на основе SPA без изучения совершенно новых интерфейсных технологий.

Начало работы с Laravel Inertia

Чтобы понять Inertia и способы ее интеграции с Laravel, мы собираемся создать веб-приложение для блога под названием CW Blog, используя самую мощную комбинацию: Laravel для серверной части, Vue.js для пользовательской части JavaScript и Tailwind CSS для стилизации.

Предварительные условия

Чтобы получить максимальную пользу от этого руководства, вы должны быть знакомы со следующим:

  • Основы Laravel (установка, база данных, миграция баз данных, модели Eloquent, контроллеры и маршрутизация)
  • Основы Vue.js (установка, структура и формы)

Шаг 1. Установите основные элементы

  • Мы начнем с создания одностраничного приложения.
  • Создайте компонент Blade для просмотра домашней страницы блога и отдельной статьи в блоге как «/resources/views/index.blade.php».
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>CW Blog</title>
  </head>
  <body>
    <header>
      <h1>CW Blog</h1>
    </header>
    <main>
      <h2>Read our latest articles</h2>
      <section>
        <article>
          <div>
            <img src="/images/CW-logo.png" alt="Article thumbnail" />
          </div>
          <h3>Title for the blog</h3>
          <p>
          </p>
          <a href="#">Read more</a>
        </article>
      </section>
    </main>
    <footer>
      <h2>Join our Newsletter</h2>
      <input type="email" />
    </footer>
  </body>
</html>

Шаг 2. Настройка блейд-файла

  • Теперь пришло время создать новый файл с расширением .blade.php.
  • Для этого в блоге/ресурсах/представлениях вашего проекта Laravel перейдите к файлу «/resources/views/show.blade.php»:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>CW Blog</title>
  </head>
  <body>
    <main>
      <article>
        <div>
          <img src="/images/CW-logo.png" alt="Article thumbnail" />
        </div>
        <h1>Title for the blog</h1>
        <p>Article content goes here</p>
      </article>
    </main>
    <footer>
      <h2>Join our Newsletter</h2>
      <input type="email" />
    </footer>
  </body>
</html>
  • Создайте новую локальную базу данных MySQL с именем CW_blog и подключите ее к своему проекту:».env»:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=CW_blog
DB_USERNAME=root
DB_PASSWORD=
  • Запустите модель базы данных, миграции и фабрики в вашем приложении laravel: «app/Models/Article.php»:
<?php
namespace AppModels;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
    use HasFactory;
    protected $fillable = ['title', 'excerpt', 'body'];
}
  • Запустите миграцию базы данных и экспортируйте демонстрационные статьи в свою базу данных в «database/migrations/create_articles_table.php»:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('excerpt');
            $table->text('body');
            $table->timestamps();
        });
    }
    public function down()
    {
        Schema::dropIfExists('articles');
    }
};
  • Запустите следующий код и создайте новый класс ArticleFactory, который будет хранить наши демонстрационные статьи в нашей базе данных.
<?php
namespace DatabaseFactories;
use Illuminate\Database\Eloquent\Factories\Factory;
class ArticleFactory extends Factory
{
    public function definition()
    {
        return [
            'title' => $this->faker->sentence(6),
            'excerpt' => $this->faker->paragraph(4),
            'body' => $this->faker->paragraph(15),
        ];
    }
}

Это все, что нам нужно для начала! Давайте приступим к делу и представим Inertia.js в наш проект.

Установка

Процесс установки Inertia разделен на два основных этапа: на стороне сервера (Laravel) и на стороне клиента (VueJs).

Официальное руководство по установке в документации Inertia немного устарело, поскольку Laravel 9 теперь по умолчанию использует Vite, но мы это тоже рассмотрим.

Шаг 1. Настройка на стороне сервера

Первое, что нам нужно сделать, это использовать терминал для установки серверных адаптеров Inertia с помощью Composer. Чтобы использовать InertiaJS с Laravel, вам необходимо установить необходимый пакет, запустив «composer require inertiajs inertia-laravel».

  • Теперь настройте корневой файл шаблона в Blade, который будет загружать ваши файлы CSS и JS, а также корень Inertia для запуска вашего приложения JavaScript. Крайне важно активировать функциональность Vite в сочетании с Laravel 9 v9.31, добавив ее в наши теги в /resources/views/app.blade.php:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <!-- Fetch project name dynamically -->
    <title inertia>{{ config('app.name', 'Laravel') }}</title>
    <!-- Scripts -->
    @vite('resources/js/app.js') @inertiaHead
  </head>
  <body class="font-sans antialiased">
    @inertia
  </body>
</html>
  • Далее мы создадим промежуточное программное обеспечение HandleInertiaRequests и опубликуем его в нашем проекте.
  • Мы можем сделать это, выполнив приведенную ниже команду терминала в корневом каталоге нашего проекта:
php artisan inertia:middleware
  • Как только это будет завершено, перейдите в «App/Http/Kernel.php» и зарегистрируйте HandleInertiaRequests в качестве последнего элемента в вашем промежуточном веб-программном обеспечении:
'web' => [
    // ...
    App\Http\Middleware\HandleInertiaRequests::class,
],

Шаг 2. Настройка клиентской части

Далее нам нужно установить зависимости Vue.js 3 для нашего внешнего интерфейса так же, как и на стороне сервера:

npm install @inertiajs/inertia @inertiajs/inertia-vue3
  • Далее вам нужно подключить Vue.js 3:
npm install vue@next
  • Обновите основной файл JavaScript, чтобы инициализировать Inertia.js с помощью Vue.js 3, Vite и Laravel:
import "./bootstrap";
import "../css/app.css";
import { createApp, h } from "vue";
import { createInertiaApp } from "@inertiajs/inertia-vue3";
import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers";
createInertiaApp({
  title: (title) => `${title} - ${appName}`,
  resolve: (name) =>
    resolvePageComponent(
      `./Pages/${name}.vue`,
      import.meta.glob("./Pages/**/*.vue")
    ),
  setup({ el, app, props, plugin }) {
    return createApp({ render: () => h(app, props) })
      .use(plugin)
      .mount(el);
  },
});
  • Мы используем плагин SolvePageComponent от Laravel и указываем ему разрешить наши компоненты из каталога ./Pages/$name.vue.
  • Это сделано для того, чтобы сохранить наши компоненты Inertia в этом каталоге позже в нашем проекте, и этот плагин поможет нам автоматически загружать эти компоненты из правильного каталога.
  • Осталось только установить vitejs/plugin-vue:
npm i @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,
        },
      },
    }),
  ],
});
  • Последний шаг — установить наши зависимости и скомпилировать файлы:
npm install
npm run dev

Вот и все. У вас есть работающее приложение Laravel 9 с Vue.js 3 и Vite.

Создание страниц Inertia

  • Теперь мы собираемся создать папку под названием «Страницы» и переместить туда ваши файлы.
  • Затем мы преобразуем компонент лезвия «.blade.php» в «.vue», сделав первую букву их имен заглавной, и превратим его содержимое в стандартный компонент Vue.js.
  • Мы переместим все теги вместе с компонентами, так как они уже включены в основной корневой компонент блейда.
<script setup>
  //
</script>
<template>
  <header>
    <h1>CW Blog</h1>
  </header>
  <main>
    <h2>Read our latest articles</h2>
    <section>
      <article>
        <div>
          <img src="/images/CW-logo.png" alt="Article thumbnail" />
        </div>
        <h3>Title for the blog</h3>
        <p>  Article Content Goes Here.</p>
        <a href="#">Read more</a>
      </article>
    </section>
  </main>
  <footer>
    <h2>Join our Newsletter</h2>
    <input type="email" />
  </footer>
</template>

Настройка show.vue

Теперь мы собираемся настроить страницу «resources/js/Pages/Show.vue», которая будет макетом нашего приложения.

<script setup>
  //
</script>
<template>
  <header>
    <h1>Welcome to CW Blog</h1>
  </header>
  <main>
    <article>
      <h1>Title for the blog</h1>
      <p>Article content goes here</p>
    </article>
  </main>
  <footer>
    <h2>Join our Newsletter</h2>
    <input type="email" />
  </footer>
</template>

Упаковка компонентов

  • Создайте папку с именем «Макеты» в «/resources/js». В этой папке создайте файл с именем «CWLayout.vue».
  • Файл будет содержать отдельные разделы для верхних и нижних колонтитулов, а основной раздел предназначен для размещения дополнительных компонентов.

Этот файл должен выглядеть так:

<script setup></script>
<template>
    <header>
    <h1>CW Blog</h1>
  </header>
  <main>
        <slot />
  </main>
  <footer>
    <h2>Join our Newsletter</h2>
    <input type="email" />
  </footer>
</template>

Создание Index.vue:

Теперь мы импортируем новый макет на наши страницы и обернем в него весь HTML-контент.

<script setup>
import CWLayout from "../Layouts/CWLayout.vue";
</script>
<template>
  <CWLayout>
    <section>
      <h2>Read our latest articles</h2>
      <article>
        <div>
          <img src="/images/CW-logo.png" alt="Article thumbnail" />
        </div>
        <h3>Title for the blog</h3>
        <p>Article content goes here!</p>
        <a href="#">Read more</a>
      </article>
    </section>
  </CWLayout>
 </template>

Show.vue:

Запустите следующий скрипт, чтобы отобразить макет, созданный в предыдущем скрипте.

<script setup>
 import CWLayout from "../Layouts/CWLayout.vue";
</script>
<template>
  <CWLayout>
    <article>
      <h1>Title for the blog</h1>
      <p>Article content goes here</p>
    </article>
  </CWLayout>
</template>

Маршруты Laravel и Inertia Render

Пришло время добавить несколько статей в нашу базу данных, которую мы создали в начале этого урока.

<?php
namespace Database\Seeders;
use App\Models\Article;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
    public function run()
    {
        Article::factory(10)->create();
    }
}

Запустите следующую команду, чтобы перенести таблицы и заполнить поддельные данные с фабрик:

php artisan migrate:fresh --seed 

Это создаст в базе данных 10 демонстрационных статей, которые нам нужно будет передать нашему представлению с помощью маршрутизации Laravel.

Вызов «routes/web.php»:

Поскольку мы используем Inertia для представлений, создайте маршрут Laravel Inertia в «routes/web.php» и верните представление домашней страницы из «/resources/js/Pages/Index.vue».

<?php
use App\Models\Article;
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;
Route::get('/', function () {
    return Inertia::render('Index', [
        'articles' => Article::latest()->get()
    ]);
})->name('home');

Перейдите в индексный файл и поместите полученную информацию в качестве props. Затем используйте v-for для отображения результатов в цикле. В тегах скрипта установите полученные данные в качестве props.

Inertia должна знать, какую информацию вы хотите получить, например, список статей.

<script setup>
import CWLayout from "../Layouts/CWLayout.vue";
  defineProps({
    articles: Object,
  });
</script>

Давайте сделаем цикл:

<template>
  <CWLayout>
    <h2>Read our latest articles</h2>
    <section>
      // Looping over articles
      <article v-for="article in articles":key="article.id">
        <div>
          <img src="/images/CW-logo.png" alt="Article thumbnail" />
        </div>
        <h3>{{article.title}}</h3>
        <p>{{article.excerpt}}</p>
        <a href="#">Read more</a>
      </article>
    </section>
  </CWLayout>
</template>

Использование Tailwind CSS с Inertia.js

  • Поскольку Tailwind уже установлен в нашем проекте в начальной точке, все, что нам нужно сделать, это указать ему читать наши компоненты Inertia. Это можно сделать, отредактировав «tailwind.config.js» следующим образом:
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./storage/framework/views/*.php",
    "./resources/views/**/*.blade.php",
    "./resources/js/**/*.vue",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};
  • Затем убедитесь, что мы импортировали наш файл CSS в «resources/js/app.js»:
import "../css/app.css";
  • И теперь мы готовы стилизовать наши компоненты в «resources/js/Pages/Index.vue»:
<script setup>
import CWLayout from "../Layouts/CWLayout.vue";
  defineProps({
    articles: Object,
  });
</script>
<template>
 <CWLayout>
    <h2 class="text-2xl font-bold py-10">Read our latest articles</h2>
    <section class="space-y-5 border-b-2 pb-10">
      <article
        v-for="article in articles"
         :key="article.id"
        class="flex justify-center items-center shadow-md bg-white rounded-xl p-4 mx-auto max-w-3xl"
      >
         <img
            src="/images/CW-logo.png"
            class="w-32 h-32 rounded-xl object-cover"
            alt=""
         />
        <div class="flex flex-col text-left justify-between pl-3 space-y-5">
          <h3
            class="text-xl font-semibold text-indigo-600 hover:text-indigo-800"
          >
            <a href="#">{{ article.title }}</a>
          </h3>
          <p>
           {{ article.excerpt }}
          </p>
          <a
            href="#"
            class="text-indigo-600 hover:text-indigo-800 w-fit self-end font-semibold"
            >Read more</a
          >
        </div>
      </article>
    </section>
 </CWLayout>
</template>
  • Добавьте новые компоненты стиля в «resources/js/Layouts/CWLayout.vue»:
<script setup></script>
<template>
    <header
        class="bg-gradient-to-r from-blue-700 via-indigo-700 to-blue-700 w-full text-center py-4"
    >
        <h1 class="text-white font-bold text-4xl">CW Blog</h1>
    </header>
    <main class="container mx-auto text-center">
        <slot />
    </main>
    <footer
        class="bg-gradient-to-b from-transparent to-gray-300 w-full text-center mt-5 py-10 mx-auto"
    >
        <h2 class="font-bold text-xl pb-5">Join our Newsletter</h2>
        <input
            class="rounded-xl w-80 h-12 px-3 py-2 shadow-md"
            type="email"
            placeholder="Write your email.."
        />
    </footer>
</template>

Готово! У вас есть работающий SPA с 10 демонстрационными блогами, использующий Laravel Inertia.

Laravel Inertia против традиционной фронтенд-разработки

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

Вот подробная сравнительная таблица, показывающая различия между Laravel Inertia и традиционной разработкой внешнего интерфейса;

Заключение

Laravel Inertia решает извечную задачу создания цельных, динамичных и отзывчивых веб-приложений, упрощая связь между серверной и внешней частью.

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

Полная интеграция Inertia с Laravel дает преимущества с точки зрения скорости разработки, обслуживания и простоты кода.

Кроме того, он упрощает управление состоянием и тестирование, что приводит к более эффективному и целостному процессу разработки по сравнению с традиционным подходом к фронтенд-разработке.