首页 > 解决方案 > 在 Vue 模板中按类别组循环遍历产品项

问题描述

我想按类别呈现产品。到目前为止,我可以使用 渲染产品v-for,但我希望根据类别渲染类似产品。

我在使用 webpack 和 Vuex 时通过 DRF 从 Django 获取数据。我知道我不能使用v-ifand v-for,所以请告诉我如何在从filteredCategorys. 我是一个新学习者,如果我不清楚这个问题,我很抱歉。

<base-card-food>
  <div v-if="isLoading">
    <base-spinner></base-spinner>
  </div>
  <ul v-else-if="hasFoods">
    <food-item
      v-for="food in filteredFoods"
      :key="food.id"
      :id="food.id"
      :name="food.name"
      :category="food.category"
      :description="food.description"
      :base_price="food.base_price"
      :photo="food.photo"
    ></food-item>
    <ul>
      <li v-for="cat in filteredCategorys" :key="cat.id">
        {{ cat.id }}
        {{ cat.name }}  
      </li>
    </ul>      
  </ul>
  <h3 v-else>No foods found.</h3>
</base-card-food>
computed: {
  filteredCategorys() {
    const categorys = this.$store.getters['categorys/categorys'];
    return categorys;
  },

  filteredFoods() {
    const foods = this.$store.getters['foods/foods'];
    return foods;
  }
}

标签: javascriptarraysvue.jsvuejs2vue-component

解决方案


使用 computed 将 items 数组重新排列为一个对象,其键是类别名称。每个键的对应值将是该类别的项目数组。这是一般的样子(之后会有一个针对您的数据的特定演示):

computed: {
  grouped() {
    const groups = {};
    this.items.forEach(item => {
      groups[item.category] = groups[item.category] || [];
      groups[item.category].push(item);
    })
    return groups;
  }
}

对类别使用外循环,对类别项使用内循环:

<div v-for="category in categories" :key="category.id">
  Category: {{ category.name }}
  <div v-for="item in grouped[category.name]" :key="item.id">
    Item: {{ item }}
  </div>
</div>

这是一个演示:

new Vue({
  el: "#app",
  data() {
    return {
      categories: [
        { id: 1, name: 'a' },
        { id: 2, name: 'b' },
        { id: 3, name: 'c' },
      ],
      items: [
        { id: 1, category: 'c', name: 'c1' },
        { id: 2, category: 'b', name: 'b1' },
        { id: 3, category: 'c', name: 'c2' },
        { id: 4, category: 'a', name: 'a1' },
        { id: 5, category: 'a', name: 'a2' },
        { id: 6, category: 'c', name: 'c3' },
        { id: 7, category: 'a', name: 'a3' },
        { id: 8, category: 'b', name: 'b2' },
      ]
    }
  },
  computed: {
    filteredFoods() {
      return this.items;  // mockup
    },
    filteredCategorys() {
      return this.categories;  // mockup
    },
    grouped() {
      const groups = {};
      this.filteredFoods.forEach(item => {
        groups[item.category] = groups[item.category] || [];
        groups[item.category].push(item);
      })
      return groups;
    }
  }
});
<div id="app">
  <div v-for="category in filteredCategorys" :key="category.id">
    Category: {{ category.name }}
    <div v-for="item in grouped[category.name]" :key="item.id">
      Item: {{ item }}
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

由于您的数据来自 Vuex,因此您可以创建grouped为 getter 而不是计算的。然后你只需要导入那个吸气剂。


推荐阅读