如何在Vue中的v-for循环中使用数组映射?

问题描述

我试图弄清楚如何使一个循环在Vue中的另一个循环内工作。在使用React时,该任务看起来微不足道,但是在View中,我不明白在处理模板/ JSX中的数组时如何使用标准的钩子。

根据条件,输入数据以给定格式来自服务器。目前,由于语法错误,下面随附的代码段中的代码无效。

您能帮我解决代码段中的错误吗?这将帮助我了解如何相对于Vue在模板中的循环中正确应用循环...

const timeStamp = moment(new Date());
var app = new Vue({
  el: "#app",template: "#app-template",data: {
    symbols: [
      {
        id: 1,name: "EURUSD",candles: [
          {
            timeStamp: timeStamp.subtract(1,"days").format("YYYY-MM-DD"),// Yesterday
            open: 1.1,close: 1.2,high: 1.3,low: 1.0,},{
            timeStamp: timeStamp.format("YYYY-MM-DD"),// Today
            open: 1.2,close: 1.5,high: 1.6,low: 1.2,}
        ]
      },{
        id: 2,name: "USDRUB",history: [
          {
            timeStamp: timeStamp.subtract(1,// Yesterday
            open: 75,close: 76,high: 77,low: 73,{
            timeStamp: timeStamp.subtract(1,// Today
            open: 76,close: 77,high: 79,low: 75,}
        ]
      }
    ]
  }
});
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script type="text/x-template" id="app-template">
  <table>
    <thead>
      <tr>
        <th>Symbol</th>
        <th>Change</th>
        <th>Time stamp</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(symbol,index) in symbols" :key="index">
        {
          symbol.candles.map(candle => {
            const { name } = symbol
            const { open } = candle.history[0]
            const { close,timeStamp } = candle.history[1]
            const change = Number.parseFloat((100 / (open / (close - open)))).toFixed(2)

            return (
              <td>{{ name }}</td>
              <td>{{ change }} %</td>
              <td>{{ timeStamp }}</td>
            )
          })
        }
      </tr>
    </tbody>
  </tabel>
</script>

解决方法

首先,您缺少结束</table>标签(您有错字:</tabel>)。

此外,我会推荐这样的方法:

    <tr v-for="(symbol,index) in symbols" :key="index">
      <template v-for="candle in symbol.candles">
        <td>{{ symbol.name }}</td>
        <td>{{ getChange(candle) }} %</td>
        <td>{{ candle.history[1].timeStamp }}</td>
      </template>
    </tr>

    ...

    methods: {
        getChange(candle) {
            const { open } = candle.history[0];
            const { close } = candle.history[1];
            return Number.parseFloat((100 / (open / (close - open)))).toFixed(2);
        }
    }

在这种情况下,<template>标记可用于您想要重复代码块而不在其周围添加额外的父标记的情况(因为<template>不会呈现为实际的HTML标记)。

我建议将逻辑移出模板并移入方法的原因是,Vue每个数据绑定仅支持一个表达式(来源:https://vuejs.org/v2/guide/syntax.html#Using-JavaScript-Expressions)。

,

谢谢您的回答,我已根据您的建议更正了代码段中的代码。该代码现在可以按预期工作。我学到的主要内容是Vue <template>组件类似于<Fragment>

的React组件

document.addEventListener('DOMContentLoaded',function() {
    const timeStamp = moment(new Date());
    var app = new Vue({
        el: "#app",template: "#app-template",data: {
            symbols: [
                {
                    id: 1,name: "EURUSD",candles: [
                        {
                            timeStamp: timeStamp
                                .subtract(1,"days")
                                .format("YYYY-MM-DD"),// Yesterday
                            open: 1.1,close: 1.2,high: 1.3,low: 1.0,},{
                            timeStamp: timeStamp.format("YYYY-MM-DD"),open: 1.2,close: 1.5,high: 1.6,low: 1.2,],{
                    id: 1,name: "USDRUB",open: 75,close: 76,high: 77,low: 73,open: 76,close: 77,high: 79,low: 75,methods: {
            moment: moment,getChange(candle) {
                const { open,close } = candle;
                return Number.parseFloat((100 / (open / (close - open)))).toFixed(2);
            }
        }
    });
});
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script type="text/x-template" id="app-template">
    <table>
        <thead>
            <tr>
                <th>Symbol</th>
                <th>Change</th>
                <th>Time stamp</th>
            </tr>
        </thead>
        <tbody>
            <template v-for="symbol in symbols">
                <tr v-for="(candle,index) in symbol.candles" :key="symbol.name + '-' + index">
                    <td>{{ symbol.name }}</td>
                    <td>{{ getChange(candle) }} %</td>
                    <td>{{ moment(candle.timeStamp).format("YYYY-MM-DD") }}</td>
                </tr>
            </template>
        </tbody>
    </table>
</script>
<div id="app"></div>