如何在 Vue js 嵌套循环中 return 只有前 5 条记录

How to return only top 5 records in Vue js nested loop

我需要在 shoppingOrder(订单)中迭代 shoppingItem(项目)。有三个命令。第一个订单有一个项目(itemid:1),第二个订单有六个项目(itemid:2,3,4,5,6,7),第三个订单有一个项目(itemid:8)。我只需要显示前五项。即 1,2,3,4,5 但当前代码只限制了第二个顺序的项目,显示里面有五个项目。最终输出像 1,2,3,4,5,6,8

如果第一个订单有五个项目,循环应该退出,如果第一个订单有一个项目,第二个订单有六个项目,它必须在订单 1 中显示 1,在 order2 中显示 2,3,4,5 并在之前退出订单3。但在我的示例中,使用 order.shoppingItem.slice(0,5) 仅限制了第二顺序的项目。它不限制项目总数。我该如何解决这个问题?我正在使用 Vue JS 版本 2

NestedLoop.vue

<template>
  <div>
    <div v-for="order in shoppingOrder" :key="order.orderId">
      <div v-for="item in order.shoppingItem.slice(0,5)" :key="item.itemId">
        {{item.itemId}}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "NestedLoop",
  data() {
    return {
      shoppingOrder: [
        {
          orderId: 1,
          orderDate: "7/30/2020",
          orderStatus: "Dispatched",
          shoppingItem: [
            {
              itemId: 1,
              itemName: "Pen",
              itemQuantity: "1",
              itemPrice: "10.00"
            }
          ]
        },
        {
          orderId: 2,
          orderDate: "7/25/2020",
          orderStatus: "Ordered",
          shoppingItem: [
            {
              itemId: 2,
              itemName: "Notebook",
              itemQuantity: "2",
              itemPrice: "40.00"
            },
            {
              itemId: 3,
              itemName: "Scale",
              itemQuantity: "3",
              itemPrice: "100.00"
            },
            {
              itemId: 4,
              itemName: "Sharpener",
              itemQuantity: "1",
              itemPrice: "10.00"
            },
            {
              itemId: 5,
              itemName: "DocumentFolder",
              itemQuantity: "1",
              itemPrice: "10.00"
            },
            {
              itemId: 6,
              itemName: "PencilBox",
              itemQuantity: "5",
              itemPrice: "140.00"
            },
            {
              itemId: 7,
              itemName: "SketchBox",
              itemQuantity: "5",
              itemPrice: "10.00"
            }
          ]
        },
        {
          orderId: 3,
          orderDate: "7/34/2020",
          orderStatus: "Dispatched",
          shoppingItem: [
            {
              itemId: 8,
              itemName: "Sketch",
              itemQuantity: "1",
              itemPrice: "10.00"
            }
          ]
        }
      ]
    };
  },
  methods: {}
};
</script>

<style scoped>
</style>

结果

1
2
3
4
5
6
8

只希望 return 像这样的前 5 项(1 按顺序 1,然后 2、3、4、5 按顺序 2),

1
2
3
4
5

只需使用计算 属性 来获取前 5 件购物商品:

computed: {
  firstShoppingItems: {
    return this.shoppingOrder.map(x => x.shoppingItem).flat().slice(0, 5);
  }
}

那么你只需要一个 v-for 循环:

<div v-for="item in firstShoppingItems" :key="item.itemId">
  {{item.itemId}}
</div>

我建议利用 Vue 的 computed properties 来制作一个限制为五个项目的列表。目前您的代码仅将内部列表分割为五个项目。

computed: {
    topFive() {
      const limit = 5;
      let count = 0;
      let res = []
      for (let i = 0; i < this.shoppingOrder.length && count < limit; i += 1) {
        let order = this.shoppingOrder[i];
        for (let j = 0; j < order.shoppingItem.length && count < limit; j += 1) {
          let item = order.shoppingItem[j];
          res.push(item);
          count++;
        }
      }
      return res;
    }

计算 属性 后,您可以从模板中调用它,如下所示:

<div v-for="item in topFive" :key="item.itemId">{{item.itemId}}</div>

我喜欢@Gaetan C 的简洁回答,但是 .flat 是一种相对较新的方法,如果您使用的是 Vue-cli 3,则需要对浏览器进行多边形填充。请参阅此 Github issue 了解更多详情。如果您 运行 遇到任何挑战,您可能需要手动编辑 babel 预设的 poly-fill 选项。

为了更好地与其他浏览器兼容,或者如果您使用的是 vue cli 2 或更低版本,我提供此解决方案。

computed: {
  firstFiveShoppingItems: {
     let initialShippingItem = [];
     for (const order of this.shoppingOrder) {
   
       if (initialShippingItem.length + order.shoppingItem.length >=5) {
         return [...initialShippingItem, ...order.shoppingItem].slice(0, 5);
       }

       initialShippingItem = [...initialShippingItem, ...order.shoppingItem]
     }
     return initialShippingItem;
  }
}

然后在您的模板中添加

<div v-for="item in firstFiveShoppingItems" :key="item.itemId">
  {{item.itemId}}
</div>

正如我所说,它不像@Gaetan C 的回答那样优雅或简洁,但它在其他浏览器中的兼容性会更好,您无需为 poly-fill 配置而头疼。

我喜欢我的解决方案的另一件事是它不会像@Gaetan C 的回答那样遍历所有购物项目数组。得到结果就断了。