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

How to use array map inside v-for loop in Vue?

我想弄清楚如何在 Vue 中让一个循环在另一个循环中工作。使用 React 时,这项任务似乎微不足道,但在 View 中,我不明白在 template/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, "days").format("YYYY-MM-DD"), // Yesterday
            open: 75,
            close: 76,
            high: 77,
            low: 73,
          },
          {
            timeStamp: timeStamp.subtract(1, "days").format("YYYY-MM-DD"), // 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",
                    candles: [
                        {
                            timeStamp: timeStamp
                                .subtract(1, "days")
                                .format("YYYY-MM-DD"),
                            open: 75,
                            close: 76,
                            high: 77,
                            low: 73,
                        },
                        {
                            timeStamp: timeStamp.format("YYYY-MM-DD"),
                            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>