Vue.js如何按分类过滤JSON产品数据并分组展示?
解决Vue.js中按分类过滤并展示JSON产品数据的问题
问题分析
你之前的v-for写法存在错误:v-for="(prod, type) in product"中的第二个参数type是数组的索引值,并非产品的type属性,所以v-if="type=='computer'"无法正确过滤产品。
解决方案:按分类分组展示(推荐)
这种方法通过计算属性将产品按type分组,再遍历分组后的数据展示,性能更优且代码更简洁。
步骤1:在HomeView.vue中导入并处理数据
<script setup> import Card from './Card.vue' // 导入你的JSON产品数据,路径根据实际情况调整 import products from './assets/products.json' import { computed } from 'vue' // 计算属性:按产品type分组 const groupedProducts = computed(() => { return products.reduce((categoryGroups, product) => { const productType = product.type // 若当前分类不存在,初始化空数组 if (!categoryGroups[productType]) { categoryGroups[productType] = [] } categoryGroups[productType].push(product) return categoryGroups }, {}) }) // 分类名称映射:将JSON中的type值转为展示用的标题 const categoryTitleMap = { computer: 'Computers', peripherals: 'Peripherals', monitor: 'Monitors' } </script>
步骤2:在模板中渲染分类与产品
<template> <div class="product-container"> <!-- 遍历每个分类 --> <section v-for="(categoryProducts, type) in groupedProducts" :key="type" class="category-section"> <!-- 显示分类标题 --> <h2>{{ categoryTitleMap[type] || type }}</h2> <!-- 渲染当前分类下的所有产品卡片 --> <div class="product-grid"> <Card v-for="product in categoryProducts" :key="product.id" :product="product" /> </div> </section> </div> </template> <style scoped> .product-container { padding: 2rem; } .category-section { margin-bottom: 3rem; } .product-grid { display: flex; flex-wrap: wrap; gap: 1.5rem; margin-top: 1rem; } </style>
备选方案:直接过滤展示(适合少量数据)
如果产品数据量较小,也可以直接在模板中通过v-if过滤每个分类的产品:
<script setup> import Card from './Card.vue' import products from './assets/products.json' </script> <template> <div class="product-container"> <!-- 电脑分类 --> <section class="category-section"> <h2>Computers</h2> <div class="product-grid"> <Card v-for="product in products" v-if="product.type === 'computer'" :key="product.id" :product="product" /> </div> </section> <!-- 外设分类 --> <section class="category-section"> <h2>Peripherals</h2> <div class="product-grid"> <Card v-for="product in products" v-if="product.type === 'peripherals'" :key="product.id" :product="product" /> </div> </section> <!-- 显示器分类 --> <section class="category-section"> <h2>Monitors</h2> <div class="product-grid"> <Card v-for="product in products" v-if="product.type === 'monitor'" :key="product.id" :product="product" /> </div> </section> </div> </template> <style scoped> .product-container { padding: 2rem; } .category-section { margin-bottom: 3rem; } .product-grid { display: flex; flex-wrap: wrap; gap: 1.5rem; margin-top: 1rem; } </style>
注意事项
- 确保你的JSON数据包含
ref和description字段(Card组件中用到了这两个属性),否则会出现渲染错误; - 如果产品数据是异步获取的(比如从API请求),只需将
products替换为响应式的请求结果即可,分组逻辑保持不变。
内容的提问来源于stack exchange,提问作者sproud
相关产品推荐
相关产品推荐

