Как передать массив из контроллера Laravel в Vue.js компонент

#laravel #vue.js

#laravel #vue.js

Вопрос:

Я хочу передать массив, вызываемый hours из контроллера Laravel, в Vue.js компонент, но по какой-то причине он не работает. Как вы можете видеть в следующем коде, я пытаюсь динамически создавать параметры внутри select, который находится внутри компонента, но по некоторым причинам я не вижу параметров в этом массиве. В представлении я создал <p> , чтобы проверить правильность возвращаемого массива из контроллера, и, наконец, он правильный, потому что в представлении я могу видеть второе значение массива. Но по некоторым причинам я не могу визуализировать значения массива внутри компонента.

Это мой код контроллера:

     $open_at = '00:00';
    $close_at = '23:45';

    $time = new DateTime($open_at);
    $close = new DateTime($close_at);
    while ($time < $close) {
        $hours[] = $time->format('H:i');
        $time->modify(' 15 minutes');
    }

    return view('create')->with('hours', $hours);
 

Это мой код представления:

 @extends('layouts.app')

@section('content')
<div class="container">
    <div id="app">
        <create-form :hours="hours"></create-form>
    </div>
    <p>
        {{ $hours[1] }}
    </p>
</div>
@endsection
 

Это код внутри компонента шаблона:

         <div class="form-group">
            <label for="start">Start Hour:</label>
            <select class="form-control" id="start">
                <option v-for="hour in hours" :key="hour.id">
                    {{ hour }}
                </option>
            </select>
        </div>
 

Это ошибка my export_default:

 export default {
    props: ['hours[]'],
    mounted() {
        console.log('Component mounted.');
        this.loadUsers();
        this.loadRooms();
    },
    data: function() {
        return {
            users: [],
            rooms: []
        }
    },
    methods: {
        loadUsers: function() {
            axios.get('api/users')
            .then((response) => {
                this.users = response.data.data;
            })
            .catch(function(error) {
                alert('noviva');
                console.log(error);
            });
        },
        loadRooms: function() {
            axios.get('api/rooms')
            .then((response) => {
                this.rooms = response.data.data;
            })
            .catch(function(error) {
                alert('noviva');
                console.log(error);
            });
        }
    }
}
 

Я визуализирую следующее предупреждение в консоли:

 Property or method "hours" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
 

Может помочь?

Ответ №1:

Определение вашего свойства props не соответствует имени, с помощью которого компоненту передается $hours

 props: ['hours'],
 

И снова у вас нет id часов, как вы создаете hours [] в контроллере, поэтому шаблон выдаст другую ошибку при попытке :key="hour.id

Вы должны либо создать массив часов в контроллере таким образом, чтобы он имел идентификатор для каждой записи, либо (не рекомендуется) вы можете использовать индекс в цикле v-for в качестве ключа

 <div class="form-group">
    <label for="start">Start Hour:</label>
    <select class="form-control" id="start">
        <option v-for="(hour, index) in hours" :key="index">
            {{ hour }}
        </option>
    </select>
</div>
 

Массивы и объекты PHP могут быть переданы в javascript / vue в качестве реквизитов путем их кодирования в формате json

     //Using the blade helper @json
    <div id="app">
        <create-form :hours='@json($hours)'></create-form>
    </div>

   //OR using json_encode()

    <div id="app">
        <create-form :hours="{{ json_encode($hours) }}"></create-form>
    </div>
 

Комментарии:

1. donkarnash использует ваш сниппет и добавляет json_encode(), это работает. Кстати, почему вы предлагаете мне не использовать ваш фрагмент?

2. Нет, это не значит, что я предлагаю вам не использовать фрагмент. В документах Vue упоминается, что не рекомендуется использовать индекс цикла как:key в циклах v-for, потому что при наличии нескольких компонентов, использующих индекс цикла в качестве ключа на одной странице, могут возникнуть некоторые побочные эффекты / непредсказуемое поведение. Поэтому, если возможно, всегда используйте уникальное свойство для итерируемого объекта как:key . Тем не менее, использование индекса цикла не является чем-то необычным.