如何按SKU分组并批量渲染商品价格列表(前端实战技巧)

先说结论:处理这类数据聚合展示问题时,核心思路其实非常清晰——先分组,再遍历。通过这种模式,能够将相同 SKU 的商品价格信息统一归拢,避免重复渲染与逻辑混乱,最终输出结构层次分明、语义正确且对搜索引擎友好的 HTML 代码。
在实际的前端开发中,数据源往往是“扁平”结构——同一个 SKU 下可能包含多条记录,分别对应不同的销售规格(例如按“件”定价、按“箱”定价)。如果直接使用单层 for 循环逐条追加 HTML,会导致同一商品标题被反复输出,显然不符合“每个 SKU 只显示一次标题,其下列出所有价格选项”的业务需求。
下面是一个直接可运行的实现方案,从数据分组到 HTML 输出,一步不落。
步骤一:按 SKU 进行数据分组
如何分组?经典做法是利用一个空对象作为哈希表,以 sku 为键,将同 SKU 的所有条目收集到一个数组中:
const groupedData = {};
for (let i = 0; i < arr.length; i++) {
const item = arr[i];
if (!groupedData[item.sku]) {
groupedData[item.sku] = [];
}
groupedData[item.sku].push(item);
}
需要特别留意的是,这里使用 const 和 let 替代了传统的 var,这不仅是现代 Ja vaScript 的推荐实践,还能有效避免变量提升带来的作用域问题,提升代码的可维护性。
步骤二:遍历分组,构建结构化的 HTML
分组完成后,接下来就是渲染输出。针对每个 SKU 分组,只取第一个条目的 sku 和 title 生成标题行,然后遍历该组内的所有条目,逐条拼接价格行:
for (const sku in groupedData) {
if (Object.prototype.hasOwnProperty.call(groupedData, sku)) {
const products = groupedData[sku];
const { sku: s, title } = products[0]; // 解构赋值,干净利落
let html = `${s} - ${title}
`;
for (let j = 0; j < products.length; j++) {
const { per, price } = products[j];
html += `${per} — ¥${parseFloat(price).toFixed(2)}
`;
}
$('#div_1').append(html);
}
}
这里有几个优化点值得强调:
- 使用
Object.prototype.hasOwnProperty.call()替代直接调用,能够更稳健地规避原型链污染风险,属于安全编码的优良习惯; - 对价格执行
parseFloat().toFixed(2)格式化,确保货币显示规范,比如1.5会正确显示为1.50; - 标题
包裹,既提升了语义可访问性,也方便后续样式控制与 SEO 权重传递; - 模板字符串的引入,让代码可读性和维护性都有了质的提升,彻底告别了老式的
+拼接方式。
注意事项
技术实现并不复杂,但有些细节还是值得多提几句:
- 避免频繁操作 DOM。 在循环里反复调用
$("#div_1").append()是性能的杀手。推荐的做法是先在内存中拼接完整的 HTML 字符串,最后一次性插入——本例正是如此。如果追求极致的前端性能,也可以考虑使用DocumentFragment进一步优化渲染效率。 - jQuery 版本兼容性。 示例基于 jQuery 3.7.1,如果项目已经迁移到原生 Ja vaScript,可以替换为
document.getElementById('div_1').insertAdjacentHTML('beforeend', html),效果完全相同且无需额外依赖。 - 数据校验不能省略。 生产环境最好加上
arr?.length和products?.[0]的空值判断,防止因数据异常而导致页面报错,增强代码的健壮性。
这套方案逻辑清晰、扩展性强,非常适合电商平台的商品列表页或价格展示场景。后续如果需要支持按 per 排序、折叠展开、或者添加“起订量”等字段,在分组后处理起来都非常便捷。可以说,这是处理同类聚合渲染场景的一个标准范式,也是前端开发者应当掌握的核心技能。
