Четыре способа передать данные из Laravel в Vue

Я работаю над проектами с Vue и Laravel последние два-три года. И в начале каждого я спрашиваю себя: «Как я собираюсь передать данные из Laravel в Vue?». Это относится как к приложениям, где компоненты Vue тесно связаны с шаблонами Blade, так и к одностраничникам, работающим совершенно независимо от бэкэнда Laravel.

Вот вам четыре различных способа передачи данных от Laravel к Vue.

Непосредственное отражение в объекте или компоненте

Передача данных из laravel в Vue

  • ЗА: просто и понятно
  • ПРОТИВ: Только с Vue, встроенным в Blade шаблон

Это самый простой способ переноса данных. Вы можете просто выводить данные в формате JSON, которые будут использоваться вашим приложением или его компонентами.

Однако самым большим недостатком этого метода является расширяемость. Ваш JavaScript должен находиться непосредственно в шаблонах, чтобы движок мог отрендерить ваши данные. Это не проблема, если вы используете Vue для добавления базовой интерактивности, но в упакованные скрипты данные уже втиснуть не получится.

Передача данных из laravel в Vue

Использование пользовательских компонентов и директивы @json в Blade позволит легко размещать данные в props’ах. Этот метод позволит вам разделять код Vue, собирая ваши скрипты вебпаком или миксом, но при этом сохраняя возможность подсовывать данные напрямую в них.

Внедрение элементов в качестве глобальных свойств окна

Передача данных из laravel в Vue

  • ЗА: Доступно во всем приложении Vue и любых других скриптах
  • Против: Довольно грязно и, как правило, не рекомендуется для больших данных

Это может показаться небольшоим хаком, но добавление данных объекту окна позволяет легко создавать глобальные переменные, доступные из любого другого скрипта или компонента, используемого в вашем приложении. В прошлом я использовал этот быстрый и грязный способ хранения и доступа к базовым адресам API, открытым ключам, определенным идентификаторам моделей и множеству других мелких элементов данных, которые мне нужно было использовать во фронтенде.

Однако при использовании этого метода есть небольшая оговорка, это то, так вы получаете доступ к данным внутри компонентов Vue. Внутри вашего шаблона вы не сможете использовать что-то похожее на приведенное ниже, поскольку Vue предполагает, что объект окна, к которому вы пытаетесь получить доступ, будет находиться внутри этого же компонента:

// не будет работать
<template>
    <div v-if="window.showSecretWindow">
        <h1>Это секретное окно, никому не говори!</h1>
    </div>
</template>

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

// будет работать
<template>
    <div v-if="showSecretWindow">
        <h1>Это секретное окно, никому не говори!</h1>
    </div>
</template>
<script>
    export default {
        computed: {
            showSecretWindow() {
                return window.showSecretWindow;
            }
        }
    }
</script>

Если вы используете этот метод для небольших строк или числовых значений и вы используете ларавельный mix для компиляции своих ресурсов, то все очень просто.

Вы можете ссылаться на переменные из файла .env в JavaScript, используя объект process.env. Например, если у меня там есть переменная API_DOMAIN=example.com, то я могу использовать process.env.API_DOMAIN в компоненте Vue (или другом JavaScript, скомпилированном с помощью mix) для доступа к этому значению.

Использование API с мидлваром Laravel и токенами CSRF

Передача данных из laravel в Vue

  • ЗА: Просто начать, идеально для одностраничных приложений (SPA)
  • ПРОТИВ: требует, чтобы ваш фронтенд рендерился в шаблонах blade

Для меня это решение стало самым простым способом начать работу в мире Vue + Laravel. Из коробки Laravel содержит два файла маршрутов: web.php и api.php. Они загружаются и мапятся через файл RouteServiceProvider.php в папке app/Providers. По умолчанию для группы web используется мидлвар web, а для группы api — мидлвар api.

Если будете разбираться, то в app/Http/Kernel.php обнаружите, что в строке 30 две группы отображаются массивами. Группа web содержит сеансы, шифрование cookie и проверка токена CSRF. А в группе API только throttle и bindings. Если ваша цель состоит в том, чтобы просто передавать данные в Vue через простой и легковесный API, который не требует аутентификации или отправки запросов, тогда вы можете остановиться прямо здесь. В противном случае можно сделать одну модификацию, которая обеспечит полную совместимость с Vue всего за несколько секунд.

Вернитесь в RouteServiceProvider, в методе mapApiRoutes смените мидлвар api на web. Что нам это даст? Это позволит маршрутам, которые мы вводим через наш API, также содержать переменные и токены сессии, которые обычно используются обычными маршрутами. Когда они вызываются с помощью axios или другого асинхронного http-клиента JavaScript, мы теперь можем использовать Auth::user() и другие методы валидации на бэкэнде.

Единственная оговорка: вам придется рендерить ваш фронтенд через Laravel и blade шаблоны. Таким образом, фреймворк может вводить необходимые токены сессии и переменные в запрос(ы).

Использование вызовов API, аутентифицированных через JWT

Передача данных из laravel в Vue

  • ЗА: Самый безопасный и «развязанный» (decoupled) вариант
  • ПРОТИВ: Требует установки и настройки стороннего пакета

JSON Web Tokens — это безопасный и простой в использовании метод блокировки доступа к вашим конечным точкам API, а использование пакета jwt-auth позволит без проблем добавить этот функционал в Laravel.

Чтобы установить и настроить JWT для вашего API, нужно выполнить несколько небольших шагов:

  • Из корня вашего приложения запустите composer require tymon/jwt-auth. Возможно вам потребуется указать версию (например, 1.0.0-rc.5)
  • Если вы используете Laravel 5.4 и ниже, добавьте строку Tymon\JWTAuth\Providers\LaravelServiceProvider::class, в массив провайдеров в файле config/app.php
  • Скопируйте себе файл конфигурации, запустив php artisan vendor:publish и выберите пакет jwt-auth
  • Запустите php artisan jwt:secret чтобы сгенерировать ключ, необходимый для подписи токенов вашего приложения.

После этого вам нужно будет указать, какие маршруты в вашем приложении будут защищены и аутентифицированы через JWT. Вы можете сделать это с помощью встроенного мидлвара или прикрутить свой собственный, который ищет токен в отправленном запросе. В методе логина вашего API вы будете использовать тот же метод auth()->attempt как и дефолтное приложении Laravel, за исключением того, что из него будет возвращаться ваш JSON Web Token, который вы должны передать обратно.

Ваше приложение Vue должно хранить этот токен (либо в LocalStorage, либо в хранилище Vuex) и добавлять его в качестве заголовка авторизации в каждый исходящий запрос, который его требует. В приложении вы можете использовать этот токен для ссылки на конкретного пользователя, который делает запросы, передавая данные, которые должны быть показаны только ему.

Автор: Andrew Schmelyun
Перевод: Demiurge Ash