V-for с вложенными объектами в массиве

У меня есть v-for в vue-bootstrap Card, который мне нужно заполнить свойствами массива объектов, которые я получаю через api.

В шаблоне:

<Card
   v-for="option in travelOptions"
   :key="option.id"
   :cardHeader="option.type | type"
   mode="Ford Mustang"
   :seats="option.trip_instance.remaining_capacity | seats"
   :date="option.trip_instance.departure_time | date"
   :time="option.trip_instance.departure_time | time"
   btnText="Select"
   @btnClicked="select()"
/>

Структура получаемого мной массива объектов примерно такая:

[
  {
    "type": "CARPOOL",
    "trip_instance": {
      "id": 23456,
      "departure_time": "2020-01-01 00:00:00",
      "remaining_capacity": 3,
      "trip": 138949,
      "vehicle": {
        "id": 1,
        "vehicle_type": {
          "category": "PERSONAL_CAR",
          "display_name": "Car Sharing"
        },
        "plate_number": "1234567890",
        "display_name": "Subaru",
        "color": "red",
        "capacity": 4
      }
    },
    "trip": {
      "id": 138949,
      "headsign": "hospital",
      "short_name": "C01",
      "direction": "0"
    },
    "pickup_point": {
      "stop": {
        "id": 36583,
        "lat": 45.1551513671875,
        "lon": 8.43579959869385,
        "stop_id": "id56757",
        "name": "il nome della fermata di pickup"
      },
      "arrival_time": "06:12:00",
      "departure_time": "06:12:00"
    },
    "dropoff_point": {
      "stop": {
        "id": 36583,
        "lat": 45.1551513671875,
        "lon": 8.43579959869385,
        "stop_id": "id909090",
        "name": "name dropOfff"
      },
      "arrival_time": "06:12:00",
      "departure_time": "06:12:00"
    },
    "reservation_type": {
      "mode": "CARPOOL"
    }
  }
]

option.type отображается нормально (находится на "первом слое" объекта) option.trip_instance.departure_time, option.trip_instance.remaining_capacity нет, они вложены в объект trip_instance. И мне нужно будет отобразить еще несколько свойств других вложенных объектов.

Раньше я имел дело с вложенными объектами при просмотре массивов (с помощью v-for), и все работало нормально, я мог получить доступ к свойствам, как в приведенном выше шаблоне. Я думал, что проблема может заключаться в отсутствии уникального идентификатора в первом слое объекта, поэтому я создал его и добавил к объектам массива прямо перед совершением действия. Новые объекты теперь имеют такую ​​внешнюю структуру:

[
    {
      id: 0
      type: 'CARPOOL',
      trip_instance: obj,
      trip: obj,
      pickup_point: obj,
      dropoff_point: obj,
      reservation_type: obj
    },
    {
      id: 1
      type: 'RENTAL',
      trip_instance: obj,
      trip: obj,
      pickup_point: obj,
      dropoff_point: obj,
      reservation_type: obj
    }
]

Это не решило проблему. Я читал о создании вложенных v-for, но у меня это не работает. Также я имею дело только с одним компонентом (картой), а не с ul и вложенными li, как в большинстве примеров, которые я нашел, предлагая это решение. Однако я попробовал, я создал div, обертывающий карту, по одному для каждого вложенного объекта. Что-то вроде

<div
  v-for="option in travelOptions"
  :key="option.id"
>
  <div
    v-for="(trip, index) in travelOptions.trip_instance"
    :key="index"
  >
    <div
      v-for="(vehicle, index) in travelOptions.vehicle"
      :key="index"
    >
      <Card
        :type="option.type"
        :time="trip.departure_time"
        :seats="trip.remaining_capacity"
      />
    </div>
  </div>
</div>

Это не работает, вся карта не отображается на экране, и из редактора (VS Code) я вижу, что v-for не «принимает» точечную нотацию. Я видел много вопросов по этой проблеме, но ни один мне не помог. Кто-нибудь может помочь? Спасибо x


person fdR    schedule 11.04.2020    source источник


Ответы (2)


Vue не позволяет динамически добавлять новые реактивные свойства корневого уровня к уже созданному экземпляру. Однако можно добавить реактивные свойства к вложенному объекту с помощью метода Vue.set (object, propertyName, value):

Vue.set(vm.someObject, 'b', 2)
// interchangeably 
this.$set(vm.someObject, 'b', 2)

Дополнительную информацию см. здесь

person jcoleau    schedule 11.04.2020
comment
Я тебя понимаю. Я получаю массив из магазина с помощью mapGetters (впервые использую помощники) и сразу использую его, не передавая данные (). Итак, следуя вашему совету, я создал пустой массив options: [] в data () и на смонтированном назначил ему travelOptions (массив, полученный из магазина). Затем я использовал параметры в v-for вместо travelOptions. (Это лучший способ использования mapGetters?) В любом случае это не решило исходную проблему. Данные вложенных объектов по-прежнему не отображаются в Карте. - person fdR; 11.04.2020
comment
Не могли бы вы поделиться кодом назначения на смонтированном, пожалуйста? - person jcoleau; 11.04.2020
comment
В любом случае его не было в data (), но это вычисляемое свойство, поэтому его изменения все еще обнаруживаются. Тем не менее, все еще борется. Не могу понять почему ... - person fdR; 14.04.2020

Виноват. Я думал, что внимательно прочитал данные, но на самом деле я этого не сделал.

Я бы сказал, что нет проблем с отображением свойств вложенных объектов с помощью v-for, просто важно, чтобы мы точно знали, что мы пытаемся отобразить в каждом цикле.

В моем случае я не заметил, что свойства объекта не всегда были одинаковыми (например, trip_instance не был свойством всех объектов в массиве, это нарушало цикл).

Итак, в надежде помочь кому-то, если у вас возникнут проблемы с v-for или итерацией в целом, убедитесь, что вы точно знаете структуру данных, с которой работаете. Надеюсь, я тоже получил это раз и навсегда.

Спасибо @djiss за ваше время и попытку помочь.

person fdR    schedule 14.04.2020