
Каждый PHP-разработчик, работая с современными JavaScript-фреймворками, наверняка задумывался о том, как было бы здорово передавать данные напрямую в компоненты без танцев вокруг контроллеров и типов данных. Арон Френсис, видимо, тоже терзал себя этим вопросом, поэтому 4 февраля 2025 года на своём ютуб-канале представил новую веху развития фронтенда на Laravel — Fusion. В этом статье мы рассмотрим базовые принципы работы библиотеки и основные нюансы работы с ней.
Концепт
У Laravel уже есть Inertia, которая позволяет использовать vue шаблоны для рендеринга, напрямую передавая туда данные из php, но всё-равно требовалось писать контроллеры и вручную передавать данные в шаблоны. Fusion решает эту проблему
Что делает Fusion:
-
Использует Vite для извлечения PHP-блоков из JavaScript-файлов и сохраняет их на диск.
-
В процессе трансляции использует Vite для добавления информации в JavaScript-файлы.
-
Запускает PHP на бэкенде, а JavaScript — на фронтенде.
-
Превращает PHP-блоки в подобие контроллеров.
-
Использует стандартный жизненный цикл запроса/ответа Laravel, включая маршрутизацию, аутентификацию, middleware и т. д.
-
Позволяет вам управлять синхронизацией состояния frontend/backend.
Можно представить <php>-блок в вашем файле как контроллер, к которому автоматически подключается состояние и добавляются вызовы методов.
Fusion поддерживает два стиля написания php-кода в SFC (single file components) — процедурный и классовый.
Процедурный:
<php> // Определяем пропс в PHP $name = prop(Auth::user()->name); </php> <template> <!-- Используем его во Vue! --> Hello {{ name }}! </template>
Class-based (классовый):
<php> new class { // Определяем пропс в PHP public string $name; public function mount() { $this->name = Auth::user()->name; } } </php> <template> <!-- Используем его во Vue! --> Hello {{ name }}! </template>
Код выше позволяет передать переменную $name в ваш шаблон Vue в качестве name. Она будет передана приложению при первой загрузке. Вам не нужно определять какие-либо пропсы на стороне Vue, библиотека позаботится об этом вместо вас.
Как работает под капотом
Теперь, чтобы разобраться с магией, мы рассмотрим жизненный цикл Fusion. Он состоит из четырёх этапов.
Запуск сборки
Когда вы выполняете npm run dev или npm run build, запускается Vite. Fusion добавляет в процесс плагин, который перехватывает работу над Vue-компонентами до того, как их обработает Vue-плагин.
Обработка PHP-блоков
Fusion-плагин ищет <php>-блоки. Если они найдены, код извлекается и передается Artisan-команде:
php artisan fusion:conform
Она, в свою очередь, делает так, что:
-
Код проходит серию парсеров, чтобы соответствовать стандарту Fusion.
-
PHP-файл записывается на диск.
Этот процесс выполняется на этапе сборки, а не во время выполнения скрипта (для экономии ресурсов).
Генерация Shim-файла
После валидации PHP-блоков выполняется команда:
php artisan fusion:shim
Она запускает следующие процессы:
-
Создается небольшой JavaScript-файл с информацией о свойствах состояния и доступных методах.
-
В этом файле находится функция
useFusion. Для каждого компонента создается своя useFusion.
Стоит заметить, что вы не обязаны импортировать useFusion, Fusion автоматически подключит ее в Vue-компонент. Однако, если хотите вручную управлять состоянием и методами, можете использовать useFusion в script или script setup.
Запросы через Laravel
После генерации PHP-класса Fusion использует стандартный жизненный цикл Laravel запросов и ответов:
-
Ходящие запросы обрабатывает FusionController, который направляет их в соответствующий PHP-класс (из Vue-шаблона).
-
Если запрос — страничный (открытие страницы), возвращается Inertia-ответ с названием нужного компонента.
-
Если отправляется запрос действия (например, вызов метода), ответ передается фронтенду для обработки.
Установка
Fusion поддерживает только Laravel приложения, использующие Inertia, но в будущем это, по словам авторов, может измениться.
Для первоначальной установки требуется поставить нужный пакет:
composer require fusionphp/fusion
После — запустить скрипт установки:
php artisan fusion:install
Скрипт сделает следующее:
-
опубликует конфиг (config/fusion.php),
-
создаст нужные директорий в storage,
-
добавит Vue-пакет в package.json,
-
изменит postinstall-скрипт и добавит fusion:install,
-
подключит Vue-плагин в resources/js/app.js,
-
подключит Vite-плагина в vite.config.js,
-
добавит post-update-cmd в composer.json,
-
выполнит миграцию внутренней SQLite-базы Fusion.
Кроме этого, Fusion создает резервные файлы ([original].backup) на случай ошибок. Копии можно удалить, если всё работает корректно.
Запуск и сборка происходит с помощью Vite, собственно, командами npm run dev и npm run build.
Маршрутизация
Fusion представляет на выбор 2 пути для маршрутизации: file-based или индивидуальное назначение маршрутов для компонентов.
File-based routing
Удобный способ автоматической маршрутизации, когда структура URL отражает структуру файлов в вашем проекте.
Для включения файлового роутинга в web.php используется метод Fusion::pages():
use Fusion\Fusion; Fusion::pages();
-
По умолчанию маршрутизируются все файлы из resources/js/Pages (настраивается в config/fusion.php под ключом paths.pages), начиная с корневого URI /.
-
Каждый .vue-файл в этой директории становится страницей, даже без <php>-блока, где название файла преобразуется в рут, например,
HelloWorld.vue→ /hello-world
Route Model Binding
Привязка моделей к маршрутам в Fusion позволяет автоматически включать экземпляры моделей Laravel в ваш код на основе параметров маршрута, вместо того чтобы вручную искать их по ID или другим ключам. Это работает аналогично стандартному механизму Laravel, но адаптировано для интеграции с файловым роутингом Fusion.
Route Model Binding используется с файловым роутингом, где параметры маршрута задаются в именах файлов с помощью квадратных скобок, например, Podcasts/[Podcast].vue. При посещении URL вроде /podcasts/1 Fusion может автоматически подтянуть модель вместо передачи строки «1».
Для получения данных в процедурном стиле достаточно использовать метод fromRoute() с указанием класса модели:
<php> $podcast = prop()->fromRoute(class: \App\Models\Podcast::class); </php>
Для классового же укажите тип параметра в методе mount или свойстве:
<php> new class { public function mount(\App\Models\Podcast $podcast) { // $podcast — экземпляр модели } } // или же new class { public \App\Models\Podcast $podcast; // Автоматически привязывается } </php>
Если модель не найдена, то вернётся ошибка 404.
Ручной роутинг
Для создания ручных маршрутов в Fusion используется метод Fusion::page() в файле web.php. Этот метод связывает конкретный URI с определённым компонентом. Вот пример:
// web.php use Fusion\Fusion; Fusion::page(uri: '/hello-world', component: 'Custom/HelloWorld');
Взаимодействие с JavaScript
Ручное управление состоянием с помощью useFusion
Кроме способа, который мы рассматривали выше, для большего контроля, получить переменную состояния из php можно с помощью композабла useFusion. Она позволяет импортировать состояние и действия в ваши JavaScript-скрипты.
<php> new class { public string $name = 'Aaron'; public string $email = 'aaron@example.com'; } </php> <script setup> import { useFusion } from '$fusion/Pages/Hello.js'; const { name } = useFusion(['name']); </script> <template> Hello {{ name }}, your email is {{ email }}! </template>
Здесь мы импортировали только name через useFusion, а email продолжает автоматически внедряться в шаблон. Это полезно, если вам нужно работать с конкретными частями состояния в JavaScript.
Если же вы хотите получить доступ ко всему состоянию, можно сделать так:
const data = useFusion();
Actions
Действия (Actions) в Fusion — это удобный механизм для взаимодействия между фронтендом (JavaScript) и бэкендом (PHP) в приложениях на Laravel. Они позволяют вызывать серверные функции из клиентской части, обеспечивая автоматическое управление состоянием, обработку ошибок и валидацию. Давайте разберём, как они работают, как их определять и использовать.
1. Процедурный стиль. В этом подходе действия задаются через функцию expose. Каждое действие передаётся как именованный аргумент в виде анонимной функции:
expose( hello: function() { return "Привет!"; }, anotherAction: function() { return "Другое действие"; } );
2. Классовый стиль. В классовом стиле действия задаются в качестве публичных методов анонимного класса. Все публичные методы становятся действиями, которые можно вызвать со стороны javascript:
new class { public function hello() { return "Привет!"; } public function anotherAction() { return "Другое действие"; } };
Если вы хотите, чтобы какой-то метод не был доступен на фронтенде, используйте атрибут #[ServerOnly]:
use Fusion\Attributes\ServerOnly; new class { #[ServerOnly] public function internalMethod() { // Этот метод доступен только на сервере } };
Синхронизация состояния между бэкендом и фронтендом
Fusion не обновляет состояние автоматически при каждом изменении на фронтенде. Вместо этого синхронизация происходит в двух случаях:
-
При вызове действий:
Когда вы вызываете действие (например, через@click="someAction"), текущее состояние фронтенда отправляется на бэкенд, обновляется там, а затем возвращается на фронтенд. -
С помощью fusion.sync:
Это магическая функция, которая позволяет вручную синхронизировать состояние.
Работа с action на клиентской части
Действия, определенные в php, становятся доступны в js как функции. Например, если на бэкенде есть метод favorite, вы можете использовать его так:
<template> <button @click="favorite">Favorite</button> </template>
Каждое действие в Fusion — это не просто функция, а прокси-объект, который содержит информацию о состоянии запроса. Это позволяет отслеживать выполнение действия и реагировать на него в интерфейсе. Доступные свойства:
-
processing: Запрос выполняется.
-
succeeded: Запрос успешно завершён.
-
recentlySucceeded: True, но становится false через 3.5 секунды (удобно для флеш-сообщений).
-
failed: Запрос завершился с ошибкой.
-
recentlyFailed: Выдает сообщение об ошибке, становится false через 3.5 секунды.
-
finished: Запрос завершён (успешно или с ошибкой).
-
recentlyFinished: Запрос завершён, становится false через 3.5 секунды.
-
error: Объект с ошибками (например, ошибки валидации из ответа 422).
-
errors: Массив сообщений об ошибках.
Пример с отслеживанием статуса:
<template> <button @click="favorite">Favorite</button> <div v-if="favorite.processing">Загрузка...</div> <div v-if="favorite.succeeded">Успех!</div> </template>
В завершение
Fusion — это мощный инструмент, который упрощает создание современных веб-приложений на Laravel и Vue.js. Благодаря Vite он обеспечивает быструю разработку и оптимизацию, а как дополнение к Inertia.js предлагает более тесную и удобную связь между фронтендом и бэкендом. На мой взгляд, это делает Fusion интересным выбором для тех, кто ищет эволюцию привычных подходов к интеграции в будущем.
НЛО прилетело и оставило здесь промокод для читателей нашего блога:
-15% на заказ любого VDS (кроме тарифа Прогрев) — HABRFIRSTVDS.
ссылка на оригинал статьи https://habr.com/ru/articles/885098/
Добавить комментарий