Vue. js - как заполнить массив при использовании v-for - PullRequest
1 голос
/ 06 января 2020

Я работаю в проекте маршрутов в Vue2. Я не буду объяснять детали, чтобы сделать этот вопрос как можно более простым.

Я использую v-for для перебора массива.

Каждый повторяющийся объект необходимо добавить в массив, который я собираюсь отправить другому компоненту в моем шаблоне.

Это сложный JSON. Я на листовой карте.

Мне нужно объединить координаты каждой точки с полилинией. Компонент <l-polyline> ожидает массив координат (каждая координата представляет собой массив из 2 значений).

Итак, я хочу поместить каждый object.coordinate в массив, пока я перебираю первый список. Затем этот массив будет передан в качестве параметра компоненту ломаной линии в шаблоне. Как мне это сделать?

<div :key="i" v-for="(route, i) in jsonResult.routesList">
    <div :key="j" v-for="(stop, j) in route.stopsList">
        <l-marker :lat-lng="latLng(stop.lat, stop.long)" />
        // the problem is here because I'm only getting one object (stop) and I need the whole list of stops to get their coordinates
        <l-polyline :lat-lngs="latLng(stop.lat, stop.long)"></l-polyline>
    </div>
</div>

Мой JSON выглядит примерно так:

Объект <l-polyline> ожидает массив, подобный этому, для рисования линий:

    [
      [20.567934, -103.366844],
      [19.54006, -99.1879349],
      [25.54193, -100.947906],
      [25.7970467, -100.59623]
    ] 

Список маршрутов (jsonResult.routesList в коде)

"routesList": [
    {
      "stopsList": [
        {
          "id": 1,
          "seq": 1,
          "start": "2019-09-10T09:32:23",
          "end": "2019-09-10T10:17:23",
          "lat": 20.567934,
          "long": -103.366844,
        },
        {
          "id": 2,
          "seq": 2,
          "start": "2019-09-10T09:32:23",
          "end": "2019-09-10T10:17:23",
          "lat": 20.587934,
          "long": -104.386844,
        }
      ],

    },
    //another route
    {
      "stopsList": [
        {
          "id": 1,
          "seq": 1,
          "start": "2019-09-10T09:32:23",
          "end": "2019-09-10T10:17:23",
          "lat": 20.567934,
          "long": -103.366844,
        },
        {
          "id": 2,
          "seq": 2,
          "start": "2019-09-10T09:32:23",
          "end": "2019-09-10T10:17:23",
          "lat": 20.587934,
          "long": -104.386844,
        }
      ],
    },

Ответы [ 2 ]

3 голосов
/ 07 января 2020

Я думаю, что проблема в том, что вы используете <div>, когда вы говорите:

<div :key="j" v-for="(stop, j) in route.stopsList">
        <l-marker :lat-lng="latLng(stop.lat, stop.long)" />
        // the problem is here because I'm only getting one object (stop) and I need the whole list of stops to get their coordinates
        <l-polyline :lat-lngs="latLng(stop.lat, stop.long)"></l-polyline>
</div>

В v-for вы передавали каждый отдельный элемент от stopList до <l-polyline> компонент. Я думаю, что правильным подходом было бы передать все stopList компоненту, а затем отформатировать его соответствующим образом (перебор массива stopList выполняется внутри компонента <l-polylist>.

<div :key="i" v-for="(route, i) in jsonResult.routesList">
      <div :key="j" v-for="(stop, j) in route.stopsList">
        <l-marker :lat-lng="latLng(stop.lat, stop.long)" />


      <l-polyline :lat-lngs="route.stopsList.map(x=>[x.lat,x.long])"></l-polyline>
</div>
</div>

Of Конечно, это не оптимальный подход, но он решит вашу проблему, лучше было бы использовать что-то, основанное на идее Давид Збиньски , и использовать вычисляемое свойство. Надеюсь, это поможет

2 голосов
/ 06 января 2020

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

// Vue component file
methods: {

  /*
   * Converts the stopsList array to an array of coordinates.
   * Example of returned value:
   *   [
   *     [ 23.1234, 21.2322 ],
   *     [ 21.1242, 24.2333 ],
   *   ]
   */
  getStopsCoordinates(stops) {
    return stops.map(stop => [ stop.lat, stop.long ]);
  }
}

Затем вы можете использовать метод getStopsCoordinates, когда вы проходите остановки координаты всех остановок, вот так:

<div :key="i" v-for="(route, i) in jsonResult.routesList">
    <div :key="j" v-for="(stop, j) in route.stopsList">
        <l-marker :lat-lng="latLng(stop.lat, stop.long)" />
        // the problem is here because I'm only getting one object (stop) and I need the whole list of stops to get their coordinates
        <l-polyline :lat-lngs="getStopsCoordinates(route.stopsList)"></l-polyline>
    </div>
</div>

Хотя это должно работать, это не оптимальное решение, так как список конвертируется каждый раз во второй v-for и, вероятно, не нужен. Есть несколько способов, как это можно оптимизировать, но без измерений и т. Д. c. Я бы, наверное, go с геттером для routesList.

// Vue component file
getters: {

  /* Returns routesList where each route has property stopsCoordinates */
  routesListWithStopsCoordinates() {
    return this.jsonResult.routesList.map(route => {
      route.stopsCoordinates = this.getStopsCoordinates(route.stopsList);
      return route;
    })
  }
},

methods: {

  /* Already explained above */
  getStopsCoordinates(stops) {
    return stops.map(stop => [ stop.lat, stop.long ]);
  }
}

Тогда в вашем шаблоне вы можете сделать что-то вроде этого:

<div :key="i" v-for="(route, i) in jsonResult.routesList">
    <div :key="j" v-for="(stop, j) in route.stopsList">
        <l-marker :lat-lng="latLng(stop.lat, stop.long)" />
        // the problem is here because I'm only getting one object (stop) and I need the whole list of stops to get their coordinates
        <l-polyline :lat-lngs="route.stopsCoordinates"></l-polyline>
    </div>
</div>

Надеюсь, это сработает.

...