
本文讲解如何使用 Vue 3(组合式 API)对本地 JSON 商品数据按 type 字段分类过滤,并通过组件化方式动态渲染不同类别的电子商品卡片,避免 v-for 与 v-if 同用的性能陷阱。
本文讲解如何使用 vue 3(组合式 api)对本地 json 商品数据按 type 字段分类过滤,并通过组件化方式动态渲染不同类别的电子商品卡片,避免 `v-for` 与 `v-if` 同用的性能陷阱。
在 Vue 应用中,将结构化的 JSON 商品数据(如电脑、外设、显示器等)按类别分组展示,是常见且实用的需求。关键在于:不直接在模板中混合使用 v-for 和 v-if——这不仅可读性差,还会导致 Vue 在每次更新时重复遍历整个数组,影响渲染性能。
推荐做法是在逻辑层预先完成数据过滤,再将精简后的数组传递给循环渲染。以你的 HomeView.vue 为例,假设你已通过 fetch 或静态导入方式加载了全部商品数据(记为 products),可按如下方式组织:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
✅ 正确写法:在 setup 中预过滤数据
<script setup>
import { ref, onMounted } from 'vue'
import Card from './components/Card.vue'
// 假设从本地 JSON 文件加载数据(示例使用静态数组,实际可用 fetch)
const products = ref([])
// 模拟异步加载 JSON 数据
onMounted(async () => {
try {
// 若使用 public 目录下的 data.json:需确保路径正确
const res = await fetch('/data.json')
products.value = await res.json()
} catch (err) {
console.error('Failed to load products:', err)
}
})
// 定义各品类过滤计算属性(响应式,自动更新)
const computers = computed(() => products.value.filter(p => p.type === 'computer'))
const peripherals = computed(() => products.value.filter(p => p.type === 'peripherals'))
const monitors = computed(() => products.value.filter(p => p.type === 'monitor'))
</script>
✅ 模板中按类别分块渲染(清晰、高效、可维护)
<template><main class="container mt-4"><!-- Computers Section --><section><h2>? Computers</h2>
<div class="row g-3">
<card v-for="prod in computers" :key="prod.id" :product="prod"></card>
</div>
</section><!-- Peripherals Section --><section class="mt-5"><h2>?️ Peripherals</h2>
<div class="row g-3">
<card v-for="prod in peripherals" :key="prod.id" :product="prod"></card>
</div>
</section><!-- Monitors Section --><section class="mt-5"><h2>?️ Monitors</h2>
<div class="row g-3">
<card v-for="prod in monitors" :key="prod.id" :product="prod"></card>
</div>
</section></main></template>
⚠️ 注意事项与最佳实践
-
不要在 v-for 元素上加 v-if:如
会强制 Vue 对每个元素执行两次判断(遍历 + 条件检查),违背响应式优化原则。 -
JSON 数据格式校验:确保你的 JSON 是合法数组(而非多个独立对象)。你提供的片段是多个 JSON 对象(无逗号分隔、未包裹在 [ ] 中),实际使用前需修正为标准格式:
[ { "id": 1, "name": "Computer number 1", "price": 1699.99, "type": "computer" }, { "id": 8, "name": "Microphone", "price": 79.99, "type": "peripherals" }, { "id": 11, "name": "Monitor 75hz", "price": 129.99, "type": "monitor" } ] -
扩展性建议:若品类较多,可封装通用过滤方法或使用 reduce() 构建分类映射对象:
const categorized = computed(() => products.value.reduce((acc, p) => { const type = p.type || 'other' acc[type] = acc[type] || [] acc[type].push(p) return acc }, {}) )然后在模板中 v-for="(items, category) in categorized" 动态渲染。
通过预过滤 + 计算属性 + 语义化分组,你不仅能实现清晰的品类展示,还能保障应用性能与长期可维护性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










