Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Які підводні камені має Vue на Blade-сторінках Laravel і в шаблонах прямо в HTML?

Vue можна використовувати не лише як SPA, а й «острівцями» на серверних сторінках Laravel: змонтувати компонент на елемент Blade-шаблону. Тут є кілька пасток.

1. Конфлікт фігурних дужок. Blade і Vue обидва використовують {{ }}. Blade обробить їх першим і спробує виконати PHP:

<div id="app">
    @{{ message }}          {{-- @ - Blade лишить {{ message }} для Vue --}}

    @verbatim
        <p>{{ user.name }}</p>   {{-- цілий блок без обробки Blade --}}
    @endverbatim
</div>

2. Шаблони в HTML (in-DOM) розбирає браузер, а не компілятор Vue:

  • регістр не враховується: <BlogPost :postTitle="t"> браузер перетворить на <blogpost :posttitle="t">. У HTML-шаблонах - лише kebab-case: <blog-post :post-title="t">;
  • самозакривних тегів немає: <my-component /> браузер прочитає як відкритий тег, і наступні елементи стануть його дітьми. Потрібно <my-component></my-component>;
  • обмеження вкладеності: у <table>, <ul>, <select> браузер викидає «чужі» теги. Компонент-рядок таблиці - через <tr is="vue:table-row">.

У .vue-файлах цих обмежень немає - їх компілює Vite.

3. Потрібна повна збірка Vue з компілятором шаблонів, якщо шаблон береться з DOM сторінки: псевдонім vue → vue/dist/vue.esm-bundler.js. Збірка більша і вимагає unsafe-eval у Content Security Policy.

4. Безпека - найважливіше. Якщо в області, на яку змонтовано Vue, є дані користувача, виведені Blade, Vue скомпілює їх як частину шаблону. Коментар із текстом {{ ... }} стане виразом Vue - Blade екранує HTML, але не фігурні дужки. Захист:

  • не монтувати Vue на області з користувацьким вмістом;
  • позначати такі ділянки v-pre (Vue не компілюватиме вміст);
  • передавати дані в компоненти через props з JSON, а не вбудовувати в розмітку.

5. Передача даних з Laravel у компонент:

<user-profile :user='@json($user)'></user-profile>
{{-- або --}}
<script>window.App = @js(['user' => $user->only('id', 'name')]);</script>

@json/Js::from безпечно екранують значення. Передавайте лише потрібні поля - усе, що в JSON, видно в коді сторінки.

Альтернативи «острівцям»: Inertia (повноцінні Vue-сторінки з маршрутизацією Laravel) або Livewire з Alpine, якщо інтерактивність помірна.

Докладніше в документації: Особливості in-DOM шаблонів

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання