Вопрос «Как использовать php-переменную в js?» периодически всплывает в чатах по ларе и у фреймворка даже есть небольшой функционал для этого, поэтому рассмотрим какие могут быть способы передачи данных между backend и frontend приложениями.
# AJAX
Самый очевидный и популярный способ, это сделать AJAX-запрос на api, в ответе получим необходимые данные, например, в json или html.
Подходит если данные не нужны во время первого выполнения и мы можем получить их позже в фоне.
Один из популярных примеров - это фильтр товаров. Поскольку выборка из базы данных может занять некоторое время, то для ускорения загрузки основной страницы (первого ответа сервера) такие запросы откладывают и запрашивают список товаров асинхронно.
# Тег <script>
Данный способ подходит, когда данные на frontend необходимы сразу. В html можно использовать тег <script> код внутри которого будет выполнен сразу после того как будет прочитан клиентом.
Данный код обычно располагают в <head> до подключения остальных скриптов.
1<script>2 var app = {{ Js::from($config) }};3 var userId = {{ Js::from(Auth::id()) }};4 var routeHome = {{ Js::from(route('home')) }};5</script>
Фасад Illuminate\Support\Js доступен начиная с 8.x версии, подробнее читай в документации .
Без хелпера необходимо вручную контролировать значения по умолчанию и следить за экранированием:
1<script>2 var app = {!! $config ? json_encode($config) : '{}' !!};3 var userId = {{ Auth::id() ?? 'null' }};4 var routeHome = '{{ route('home') }}';5</script>
Обрати внимание, что такие переменные являются глобальными , а это bad-практика. Тем не менее, если приходится использовать данный способ, то рекомендую свести количество переменных к минимуму и дать уникальное имя, например с префиксом имени проекта, а обращаться к ним через window
# HTML-атрибут
Аналогично предыдущему способу, только вместо JS переменной передаём значение в data-* атрибут тега, а затем, после загрузки DOM, читаем атрибут тега.
1<button data-href="{{ route('posts.create') }}">click</button>
1// js2const button = document.querySelector('button')3const href = button.getAttribute('data-href')
Или как массив/объект:
1<input data-params='@json($params)' />
1// js2const input = document.querySelector('input')3const params = JSON.parse(input.getAttribute('data-params'))
Способ подходит лучше для передачи мелких, локальных (не глобальных) данных, например, адрес, куда необходимо отправить данные после выполнения каких-либо асинхронных действий, вызываемых по клику на элемент. Ещё один пример - передача параметров для слайдера, модального окна или любого другого компонента, которые могут контролироваться backend-ом.
# Готовые решения
tighten/ziggy
Если необходимо пробросить маршруты в JS.
rmariuzzo/Laravel-JS-Localization
Если необходимо пробросить переводы (локализацию) в JS.
Inertiajs
Глобальный пакет для монолитного SPA, который использует вариант с HTML-атрибутом, описанный выше.
Не стоит использовать для простого проброса данных, а только для цельных приложений,
например, хорошо подходит для админок.