Современная интеграция JavaScript в Laravel с использованием Vite, Livewire и Inertia

Раздел: Laravel -> Интеграция JavaScript в Laravel

Основные подходы к интеграции JavaScript в Laravel

Эффективное решение: использование Vite и data-атрибутов

В современных версиях Laravel (начиная с 9) основным инструментом для сборки JavaScript и CSS является Vite. Он обеспечивает быструю горячую перезагрузку, модульность и оптимизацию. Для передачи данных из PHP в JavaScript рекомендуется использовать data-атрибуты в HTML или встроенные JSON-скрипты. Это исключает прямую интерполяцию в JavaScript-коде и снижает риск XSS.


{{-- Blade-шаблон --}}

Php js laravel (laravel и javascript)

Пояснение: атрибуты data- ... автоматически становятся доступными через dataset. json_encode экранирует специальные символы. При использовании Vite скрипты подключаются через @vite('resources/js/app.js') и могут обрабатываться как модули.

Типичная ошибка:

Прямая вставка PHP-переменной в JavaScript без экранирования: var name = '{{ $name }}'; - приводит к XSS, если $name содержит кавычки. Решение: использовать @json или json_encode с data-атрибутами, а также функцию js_escape() или Javascript::encode() из пакетов.

Как передать массив или коллекцию в JavaScript без ручного кодирования?

В Laravel доступна директива Blade @json, которая автоматически экранирует данные и преобразует их в JSON. Это удобно для простых переменных.



Проблема: @json выводит JSON прямо в JavaScript-контекст. Если данные содержат HTML-теги, они экранируются, но это не защищает от XSS при неправильном использовании. Всегда используйте @json только для данных, а не для пользовательского ввода, который будет интерпретироваться как HTML.

Как организовать реактивное взаимодействие без перезагрузки страницы (Livewire)?

Laravel Livewire - это полноценный фреймворк для создания динамических интерфейсов на серверном рендеринге. Он автоматически обновляет части страницы через AJAX, используя Alpine.js или собственный JavaScript.


// Компонент Livewire (app/Http/Livewire/Counter.php)
class Counter extends Component
{
    public $count = 0;
    public function increment()
    {
        $this->count++;
    }
    public function render()
    {
        return view('livewire.counter');
    }
}

{{-- blade-шаблон --}}

{{ $count }}

Пояснение: Livewire использует wire:click для привязки события. Всё обновление происходит через AJAX, JavaScript-код не требуется писать вручную. Подходит для простых CRUD, форм, фильтров.

Ошибка: Неправильная установка Livewire (не выполнена команда php artisan livewire:install или отсутствует подключение пакета). Симптом: кнопка не реагирует. Решение: проверить установку и наличие @livewireStyles, @livewireScripts и скрипта Alpine.js.

Как построить SPA на основе Laravel и Vue/React (Inertia.js)?

Inertia.js - это адаптер, позволяющий использовать современный фронтенд (Vue, React, Svelte) без создания отдельного REST API. Данные передаются вместе с HTML-ответом в виде JSON-свойства «page».


// routes/web.php
Route::get('/dashboard', function () {
    return Inertia\Inertia::render('Dashboard', [
        'users' => User::all()
    ]);
});

// resources/js/Pages/Dashboard.vue


Пояснение: Inertia автоматически сериализует данные и передаёт их в компонент. Навигация и обновление данных происходит без полной перезагрузки.

Типичная проблема: Неверно указан адаптер (например, используется React вместо Vue в конфиге). Решение: проверить файл app/Providers/AppServiceProvider.php и установить соответствующий пакет (inertiajs/inertia-laravel + inertiajs/inertia-vue3).

Как отправлять AJAX-запросы в Laravel из внешнего JavaScript-приложения?

Использовать Axios (встроен в Laravel Breeze/ Jetstream) или Fetch API. Для аутентификации используется CSRF-токен, который Laravel автоматически передаёт через куки или meta-тег.


// resources/js/bootstrap.js
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

// Использование
axios.get('/api/user').then(response => {
    console.log(response.data);
});

Пояснение: Для API-маршрутов (routes/api.php) не требуется CSRF-защита, если используется аутентификация через Bearer-токен. Для веб-маршрутов необходимо передавать токен через мета-тег или куки.

Ошибка: 419 ошибка (CSRF token mismatch). Решение: добавить в скрипты получение токена из meta-тега и включение его в заголовки Axios:


let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
}

Расширенные примеры интеграции JavaScript в Laravel

Пример 1. Динамический поиск с использованием Livewire и Alpine.js

Создадим компонент поиска, который отправляет запрос на сервер при вводе текста и отображает результаты без перезагрузки.

Пример

// app/Http/Livewire/Search.php
namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Post;

class Search extends Component
{
    public $query = '';
    public $posts = [];

    public function updatedQuery()
    {
        $this->posts = Post::where('title', 'like', '%'.$this->query.'%')
                            ->take(5)
                            ->get();
    }

    public function render()
    {
        return view('livewire.search');
    }
}
Пример

{{-- resources/views/livewire/search.blade.php --}}
    @foreach($posts as $post)
  • {{ $post->title }}
  • @endforeach

Результат: при вводе текста с задержкой 300 мс выполняется AJAX-запрос, обновляется список.

(пользователь вводит 'laravel')
  • Laravel для начинающих
  • Интеграция Laravel и React

Пример 2. Передача сложных объектов через data-атрибуты

Передадим вложенные данные с помощью сериализации и разберём на клиенте.

Пример

// Blade
@php
    $nested = [
        'user' => ['name' => 'Анна', 'age' => 30],
        'meta' => ['theme' => 'light', 'locale' => 'ru']
    ];
@endphp
Вывод в консоль: Анна

Пример 3. Использование Axios с защитой CSRF в SPA на Vue (Breeze)

Laravel Breeze устанавливает скрипты для обработки CSRF. Пример отправки формы через Axios.

Пример

{{-- В blade шаблоне --}}


// resources/js/components/LoginForm.vue


Пояснение: Axios автоматически считывает CSRF-токен из meta-тега, если он настроен в bootstrap.js. Возможная ошибка: токен не передан при первом запросе - необходимо убедиться, что meta-тег присутствует на странице.

Пример 4. Inertia.js: работа с сессионными flash-сообщениями

Inertia поддерживает flash-сообщения, которые отправляются вместе с ответом. Пример на сервере:

Пример

// контроллер
public function store(Request $request)
{
    // ... логика
    return redirect()->back()->with('success', 'Данные сохранены!');
}

Во vue-компоненте flash-сообщения доступны через свойство $page.props.flash:

Пример


Пример вывода: если произошло сохранение, на странице появится зелёное сообщение.

(после редиректа)
Данные сохранены!

Пример 5. Использование библиотеки Laravel Echo и Pusher для реального времени

Интеграция с WebSockets через Laravel Echo. Необходимо установить pusher/pusher-php-server и laravel-echo.

Пример

// config/broadcasting.php
'default' => env('BROADCAST_DRIVER', 'pusher'),

// ресурс bootstrap.js
import Echo from 'laravel-echo';
window.Pusher = require('pusher-js');

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: process.env.MIX_PUSHER_APP_KEY,
    cluster: process.env.MIX_PUSHER_APP_CLUSTER,
    forceTLS: true
});

// прослушивание события
Echo.channel('orders')
    .listen('OrderShipped', (e) => {
        console.log('Заказ отправлен:', e.order);
    });

Результат: при вызове события OrderShipped на сервере, все подключённые клиенты получат уведомление.

Консоль: "Заказ отправлен: { id: 42, status: 'shipped' }"

Пример 6. Ленивая загрузка больших JavaScript-файлов через динамические импорты

Vite поддерживает динамические импорты, которые разбивают код на части. В Laravel это работает из коробки.

Пример

// resources/js/components/HeavyComponent.js
export default function() {
    console.log('Тяжелый компонент загружен');
}

// resources/js/app.js
import('/components/HeavyComponent.js').then(module => {
    module.default();
});

При сборке Vite создаст отдельный чанк для HeavyComponent. Он загрузится только при выполнении импорта.

(в консоли) "Тяжелый компонент загружен"

Laravel и JavaScript - comments

En
Php js laravel (php)