Vue.js – 如何在使用 v-for 时填充一个数组

huangapple go评论78阅读模式
英文:

Vue.js - how to fill an array while using v-for

问题

我在Vue2的路由项目中工作。我不会解释细节,以尽可能简化这个问题。

我使用v-for来迭代一个数组。

每个迭代的对象需要添加到一个数组中,我将在模板中发送到另一个组件。

这是一个复杂的JSON。我在Leaflet地图上。

我需要将每个点的坐标与折线连接起来。<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)" />
        // 问题出在这里,因为我只得到一个对象(stop),而我需要获取它们的坐标的整个停靠点列表
        <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
        }
      ]
    },
    //另一条路线
    {
      "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
        }
      ]
    }
]
英文:

I'm working in a routes project in Vue2. I won't explain the details to make this question as simple as possible.

I'm using a v-for to iterate through an array.

Each iterated object needs to be added to an array which I'm going to send to another component in my template.

It's a complex JSON. I'm on a leaflet map.

I need to join each point's coordinate with a polyline. The &lt;l-polyline&gt; component is expecting an array of coordinates (each coordinate is an array of 2 values).

So, my take is to put each object.coordinate into an array as I iterate over the first list. Then that array is going to be passed as a parameter to the polyline component in the template. How do I do that?

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

My JSON looks more or less like this:

The &lt;l-polyline&gt; object expects an array like this to draw the lines:

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

The routes list (jsonResult.routesList in the code)

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

答案1

得分: 3

我认为问题出在你使用&lt;div&gt;的方式上,当你说:

&lt;div :key=&quot;j&quot; v-for=&quot;(stop, j) in route.stopsList&quot;&gt;
        &lt;l-marker :lat-lng=&quot;latLng(stop.lat, stop.long)&quot; /&gt;
        // 这里的问题在于我只得到了一个对象(stop),而我需要整个停靠点列表来获取它们的坐标
        &lt;l-polyline :lat-lngs=&quot;latLng(stop.lat, stop.long)&quot;&gt;&lt;/l-polyline&gt;
&lt;/div&gt;

v-for中,你正在将每个单独的元素从stopList传递给&lt;l-polyline&gt;组件。我认为正确的方法是将整个stopList传递给组件,然后进行相应的格式化(在&lt;l-polylist&gt;组件内部迭代stopList数组)。

&lt;div :key=&quot;i&quot; v-for=&quot;(route, i) in jsonResult.routesList&quot;&gt;
      &lt;div :key=&quot;j&quot; v-for=&quot;(stop, j) in route.stopsList&quot;&gt;
        &lt;l-marker :lat-lng=&quot;latLng(stop.lat, stop.long)&quot; /&gt;
        
    
      &lt;l-polyline :lat-lngs=&quot;route.stopsList.map(x=&gt;[x.lat,x.long])&quot;&gt;&lt;/l-polyline&gt;
&lt;/div&gt;
&lt;/div&gt;

当然,这不是最优化的方法,但它将解决你的问题。更好的方式是使用基于Dawid Zbiński的思路,并使用计算属性。希望这对你有所帮助。

英文:

I think the problem is in the way that your using your &lt;div&gt;, when you say:

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

In the v-for you were passing each individual element from the stopList to the &lt;l-polyline&gt; component. I think the correct approach would be to pass the whole stopList to the component, and then format it accordingly (iterating over the stopList array is done inside the &lt;l-polylist&gt; component.

&lt;div :key=&quot;i&quot; v-for=&quot;(route, i) in jsonResult.routesList&quot;&gt;
      &lt;div :key=&quot;j&quot; v-for=&quot;(stop, j) in route.stopsList&quot;&gt;
        &lt;l-marker :lat-lng=&quot;latLng(stop.lat, stop.long)&quot; /&gt;
        
    
      &lt;l-polyline :lat-lngs=&quot;route.stopsList.map(x=&gt;[x.lat,x.long])&quot;&gt;&lt;/l-polyline&gt;
&lt;/div&gt;
&lt;/div&gt;

Of course this is not an optimal approach, but it will solve your problem, a better way would be using something based on the idea of Dawid Zbiński and use a computed property. I hope this helps

答案2

得分: 2

你应该使用一个方法来计算要传递给另一个组件的坐标数组。

// Vue 组件文件
methods: {
  
  /*
   * 将 stopsList 数组转换为坐标数组。
   * 返回值示例:
   *   [
   *     [ 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)" />
        // 问题在这里,因为我只获取到一个对象(stop),我需要整个站点列表以获取它们的坐标
        <l-polyline :lat-lngs="getStopsCoordinates(route.stopsList)"></l-polyline>
    </div>
</div>

虽然这应该可以工作,但不是最佳解决方案,因为列表在第二个 v-for 中每次都被转换,这可能是不必要的。有多种方法可以进行优化,但没有测量等信息,我可能会选择为 routesList 创建一个 getter。

// Vue 组件文件
getters: {

  /* 返回具有属性 stopsCoordinates 的 routesList */
  routesListWithStopsCoordinates() {
    return this.jsonResult.routesList.map(route => {
      route.stopsCoordinates = this.getStopsCoordinates(route.stopsList);
      return route;
    })
  }
},

methods: {

  /* 如上所述 */
  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)" />
        // 问题在这里,因为我只获取到一个对象(stop),我需要整个站点列表以获取它们的坐标
        <l-polyline :lat-lngs="route.stopsCoordinates"></l-polyline>
    </div>
</div>

希望这对您有帮助。

英文:

You should use a method in order to compute the array of coordinates you want to pass to the other component.

// 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 =&gt; [ stop.lat, stop.long ]);
  }
}

You can then use the getStopsCoordinates method when you're passing the stops coordinates of all stops, like so:

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

Although it should work, it's not an optimal solution, as the list is converted each time in the second v-for and it's probably not needed. There's multiple ways on how this can be optimised, but without the measurements etc. I'd probably go with a getter for routesList.

// Vue component file
getters: {

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

methods: {

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

Then in your template you can do something like this:

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

Hope it works.

huangapple
  • 本文由 发表于 2020年1月6日 18:29:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/59610456.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定