/ Vue Js

Как передать данные в компонент VueJs из Laravel

Очень часто при разработке на Laravel я использую VueJs для построения крутых и прогрессивных шаблонов. Но, при работе я очень часто сталкивался с проблемой - моему компоненты необходимо получать инициализирующие данные от системы. И сегодня я расскажу, как можно передать данные: массивы, объекты, булевы значения, или любые другие примитивные данные от приложения Laravel компонентам VueJs.

Есть 2 опции решения поставленной задачи:

  • Можно создать API. И из компонента выполнить запрос на получение нужных данных, после чего обработать, когда компонент будет смонтирован.
  • Можно передать все данные в компонент в самом blade-шаблоне, закодировав их в JSON.

Выбор решения зависим от ситуации и задач. Создание API для получения нужных данных выглядит более комплексно и продвинуто. Однако бывают случаи, когда всё же лучше передать необходимые данные прямо из представления, во время вызова самого компонента.

На сегодня я выбрал второй вариант: потому что он уменьшит количество запросов, необходимых для рендеринга страницы. Так же, я решил не создавать API, потому что это дополнительная работа: в API так же нужно будет предусмотреть проверку разрешений на получение данных, и соответствующе всё описать. К тому же, когда у вас уже готовы контроллеры, представления, где описаны все проверки, и хотелось бы быстрее передать данные компоненту, не описывая дополнительную логику приложения - это идеальный вариант.

Кодирование данных в удобный формат для передачи

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

{!! json_encode($data) !!}

Этот код преобразует данные из переменной $data в JSON, который JavaScript сможет обработать без дополнительных усилий и преобразований.

А тем, кто использует Laravel версии 5.6 и выше, ещё проще. Теперь вы можете вызвать сокращенную конструкцию в blade-шаблоне, и данные будут перекодированы в JSON аналогично коду выше:

@json($data)

То есть, чтобы преобразовать PHP-массив в JavaScript, то достаточно вызвать:

<script>
    var data = <?= json_encode($data) ?>;
    // или с помощью директивы Laravel
    var data = @json($data);
</script>

Передача данных в компонент VueJs

Теперь, так как мы знаем, как кодировать данные, осталось только передать этот JSON в нужный компонент, вызвав его из blade шаблона. Для наглядной демонстрации процесса, напишем простой компонент, принимающий разные данные от приложения.

Напишем компонент, и назовём его AppComponent.vue:

<template>
    <div>
        <ul class="list-group">
            <li class="list-group-item" v-for="item in data">
                <span class="badge badge-primary">#{{ item.id }}</span> {{ item.name }}
            </li>
        </ul>
    </div>
</template>

<script>
    export default {
        name: 'AppComponent',
        props: ['data'],
        mounted () {
            // Как-то обрабатываем данные
            console.log(this.data)
        }
    }
</script>

Теперь всё, что мне нужно - зарегистрировать этот компонент во Vue (в Laravel из коробки регистрация компонентов, написания основного JS-кода производится в файле app.js)

Vue.component('app-component', require('./components/AppComponent.vue'));

// или же, в новой версии
//Vue.component('app-component', require('./components/AppComponent.vue').default);

Теперь, представим, что мы получаем какие-то данные в контроллере, и передаём их в представление:

$data = [
    ['id' => 1, 'name' => 'Admin'],
    ['id' => 2, 'name' => 'Truehero'],
    ['id' => 3, 'name' => 'Truecoder'],
];

return view('test', ['data' => $data]);

И всё, что осталось - вызвать в представлении ранее зарегистрированный компонент, и передача ему нужных параметров:

<app-component :data='{!! json_encode($data) !!}' />

{{--или короче, используя Laravel директиву--}}
<app-component :data='@json($data)' />

Прошу заметить, для того, чтобы данные передавались Vue-компоненту в валидном формате, в передаваемых параметрах компонента нужно указывать не двойные кавычки, а одинарные:

{{--так нужно--}}
<app-component :data='@json($data)' />


{{--так нельзя--}}
<app-component :data="@json($data)" />

И в результате получим результат, который демонстрирует то, что мы смогли успешно передать массив данных из Laravel во VueJs resul_render_list

И вот, оказывается настолько просто передать массив данных от приложения во VueJs компонент. Этот подход позволяет создать более универсальные компоненты. Теперь Vue компоненты не обязаны получать данные из глобального объекта window, или ему подобных.

Теперь компонент принимает все необходимые для работы параметры из верхнего слоя приложения. Потому, чтобы получить данные в компоненте VueJs из приложения Laravel, достаточно вызвать Vue-компонент из шаблона blade, передав ему необходимые параметры. А уже внутри самого компонента, прочитаем данные (массив, объект, или булево значение) через props.

Кстати, такой формат передачи данных удобен не только при передаче данных во VueJs компоненты, но и в data-атрибуты. Например, если вы используете JQuery вместо VueJs, то можете так же задавать данные любому html-тегу:

<div class="item" data-users='@json($data)'></div>

Почему внутри компонента мы не выполняем декодирование JSON-а?

Так устроен VueJs. Если передавать Vue компоненту какой-то параметр таким образом:

<app-component data='@json($data)' />

То props-параметр data в компоненте будет читаться как строка, в любом случае. Например, если вывести на экран данные из props.data, получим: string_data

Однако, если эти же данные передать в таком виде (добавив : перед именем параметра):

<app-component :data='@json($data)' />

То эта конструкция говорит, что передаваемые данные являются вычисляемой JS-конструкцией (булево значение, объект, массив, число типа int, функция, ...).

И в нашем случае, данные будут сразу получены в виде JavaScript массива объектов: js_result

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

Как передать булево значение компоненту VueJs

Представим, что наш компонент требует от приложения булево значение: true, или false. И, как мы выяснили ранее, чтобы передать вычисляемую конструкцию, а не строку, то нужно выполнить:

<app-component :data='true' />

{{--а так параметр будет воспринят как строка--}}
<app-component data='true' />

boll_result

Резюме

Теперь вы можете проверить все разрешения пользователя на получение данных в контроллерах, или представлениях, дополнительно не создавая API со своими правилами проверок. Теперь вы можете переложить на компонент ответственность только за рендеринг и обработку переданных ему данных из blade представления.

Прочитав эту статью вы научились работать с VueJs из Blade шаблонов, передавать компоненту разные типы данных из PHP и Laravel. Используя данный подход, вы можете настроить все проверки разрешений пользователя в blade шаблонах, не напрягая этим Vue-компоненты.

В этой статье я продемонстрировал, как во VueJs передать массив, и получить его через props внутри компонента, а так же, как работать с другими типами данными, принимать их, и обрабатывать на "другой стороне". Теперь вы знаете как связать данные, получаемый от бекенда на Laravel (или php) и фронтенд на VueJs.