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

3

我正在尝试在Vue中使一个循环工作在另一个循环内。在React中,这个任务似乎很简单,但是在Vue中,当我需要在模板/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>


你正在尝试迭代 symbol.candles - 这根本不存在。 - Jaromanda X
你在数据打字错误方面是正确的,history属性不存在。 - north.inhale
2个回答

3
首先,你缺少了闭合的</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);
        }
    }
< p > <template> 标签可用于这种情况,您想重复一段代码而不添加额外的父标签(因为<template> 不会呈现为实际的HTML标签)。

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


0
感谢您的答案,我已经根据您的建议更正了代码片段中的代码。现在代码按照预期工作。我学到的主要内容是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>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接