mcpField
P
product-comparison

product-comparison

github.com/finsilabs设计与 UI60301 次安装6 天前更新
代码仓库

关于 product-comparison

product-comparison 是一项技能,用于规划网店的并排商品比较体验,涵盖平台配置和自定义实现,包括 URL 选品、固定表头及隐藏相同属性。

主要功能

  1. 01在表格中比较 2–4 件商品
  2. 02隐藏属性相同的行
  3. 03将比较状态保存在 URL 中
  4. 04配置主流电商平台的比较功能
  5. 05整理并突出显示商品属性
  6. 06支持可滚动的移动端表格

适用场景

  1. 01为网店添加商品比较功能
  2. 02帮助顾客评估技术规格
  3. 03让 B2B 买家分享采购比较结果
  4. 04为无头网店构建自定义比较页面

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill product-comparison

安装后在 Claude Code 中输入/product-comparison确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

tile.json
evals/accessible-comparison-table-with-attribu/
criteria.json
task.md
evals/compare-checkboxes-and-floating-comparis/
criteria.json
task.md
evals/url-state-management-and-attribute-norma/
criteria.json
task.md

详细介绍

产品对比

概述

构建并排产品对比功能,让购物者选择 2–4 件产品,并在固定表头的表格中查看它们的属性。可以隐藏所有所选产品中完全相同的属性行,减少干扰。对比状态会存储在 URL 中,方便分享或加入书签。

何时使用此技能

  • 销售技术规格繁多的产品时(电子产品、家电、相机)
  • 转化率调研显示,购物者在购买前会比较多件产品时
  • 产品目录中的属性数据结构完善,适合用于对比时
  • 构建 B2B 商店,买家需要向利益相关者说明购买决策的合理性时
  • 在产品列表页实现“对比”复选框时

核心说明

第 1 步:确定商家的平台并选择合适的方法
平台推荐方法原因
Shopify安装 Comparify 或 Product Compare 应用(两者均提供免费套餐)Shopify 没有内置对比功能;这些应用会在产品卡片上添加“对比”按钮、浮动对比栏和完整的对比表格页面,并从产品元字段中提取规格数据
WooCommerce安装 YITH WooCommerce Compare(免费)或 WooCommerce Products CompareYITH Compare 是最受欢迎的免费选项,可在产品卡片上添加“对比”复选框,使用 WooCommerce 产品属性生成对比表格页面,并提供“仅显示差异”开关
BigCommerce在 Storefront → My Themes → Customize 中启用内置的 Compare 功能(Cornerstone 主题)BigCommerce 和 Cornerstone 支持原生产品对比,可在主题编辑器中启用;该功能使用产品自定义字段作为对比属性
自定义 / 无头架构使用产品属性数据构建 URL 状态对比栏和对比表格页面可全面控制属性显示、差异突出显示和表格布局;请参阅下方的实现方法
第 2 步:在平台上启用并配置对比功能

Shopify

使用 Comparify 应用:

  1. 从 Shopify App Store 安装 Comparify – Product Comparison(提供免费套餐)
  2. 在应用设置中选择要作为对比行显示的产品元字段(例如,材质、重量、尺寸、保修)
    • 如果尚未设置元字段:前往 Settings → Custom data → Products,为规格创建元字段
  3. 应用会自动在系列页面的产品卡片上添加“对比”复选框
  4. 购物者最多可选择 4 件产品,点击浮动对比栏中的“对比”,即可进入完整的对比表格
  5. 在应用的 Table Settings 中配置要显示的属性及其顺序

准备产品数据:

  • 将规格数据添加为产品元字段(推荐),或使用统一格式将其添加到产品描述中
  • 对于变体规格,将其添加为变体元字段(例如,每种尺码对应的重量)

WooCommerce

使用 YITH WooCommerce Compare(免费):

  1. 从 WordPress.org 安装并启用
  2. 前往 YITH → Compare → Settings
  3. 在 Fields to compare 下,选择要作为行显示的 WooCommerce 产品属性和自定义字段(例如,颜色、材质、尺寸、重量)
  4. 将 Maximum products 设为 4
  5. 启用 Highlight differences,以醒目显示产品存在差异的行
  6. 该插件会在商店页面和存档页面的产品卡片上添加“对比”按钮
  7. 购物者添加产品时,页面底部会显示浮动对比栏

准备产品数据:

  • 通过 Products → Attributes 添加对比属性——创建“材质”“保修”“兼容对象”等属性,并为每件产品指定相应的值
  • 产品必须使用相同的属性名称,对比行才能正确对齐

BigCommerce

内置对比功能(Cornerstone 主题):

  1. 前往 Storefront → My Themes → Customize
  2. 导航至 Global → Product Compare(或 Category Page → Product Compare,具体取决于主题版本)
  3. 将 Enable product comparison 切换为开启
  4. 设置 Maximum products(默认值为 4)
  5. 在 Products → Product Custom Fields 设置中配置要作为对比行显示的 Product Custom Fields
  6. 顾客会在商品卡片上看到“Compare”复选框;浮动对比栏会自动显示

添加规格数据:

  • 前往 Products → [product] → Custom Fields,添加名称/值对(例如,“屏幕尺寸:15.6 英寸”“电池续航时间:10 小时”)
  • 对可对比的商品使用相同的字段名称,以便它们在对比表中对齐

自定义 / 无头架构

对比栏(选择商品时显示的浮动栏):

// ComparisonTray.jsx
export function ComparisonTray({ selectedProducts, onRemove, onClear }) {
  if (selectedProducts.length === 0) return null;

  const compareUrl = `/compare?${selectedProducts.map(p => `compare=${p.id}`).join('&')}`;

  return (
    <div className="comparison-tray" aria-live="polite" aria-label="Products selected for comparison">
      <div className="tray-products">
        {selectedProducts.map(product => (
          <div key={product.id} className="tray-product">
            <img src={product.image} alt={product.name} width="48" height="48" />
            <button onClick={() => onRemove(product.id)} aria-label={`Remove ${product.name} from comparison`}>&times;</button>
          </div>
        ))}
        {Array.from({ length: Math.max(0, 4 - selectedProducts.length) }).map((_, i) => (
          <div key={`empty-${i}`} className="tray-placeholder" aria-hidden="true">+</div>
        ))}
      </div>
      <div className="tray-actions">
        <a href={compareUrl} className="btn-primary" aria-disabled={selectedProducts.length < 2}>
          Compare ({selectedProducts.length})
        </a>
        <button onClick={onClear}>Clear all</button>
      </div>
    </div>
  );
}

带粘性表头和差异高亮的对比表:

export function ProductComparisonTable({ products, attributeGroups, showOnlyDifferences }) {
  function isRowIdentical(attrKey) {
    const values = products.map(p => p.attributes[attrKey]);
    return values.every(v => v === values[0]);
  }

  return (
    <div className="comparison-wrapper" style={{ overflowX: 'auto' }}>
      <table className="comparison-table">
        <caption className="sr-only">
          Side-by-side comparison of {products.map(p => p.name).join(', ')}
        </caption>
        <thead>
          <tr>
            <th scope="col" className="attr-col">Attribute</th>
            {products.map(product => (
              <th key={product.id} scope="col">
                <img src={product.image} alt={product.name} width="80" height="80" />
                <a href={product.url}>{product.name}</a>
                <strong>${product.price}</strong>
                <button className="btn-primary">Add to Cart</button>
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {attributeGroups.map(group => (
            <>
              <tr key={`group-${group.label}`}>
                <th scope="rowgroup" colSpan={products.length + 1}>{group.label}</th>
              </tr>
              {group.attributes.map(attrKey => {
                if (showOnlyDifferences && isRowIdentical(attrKey)) return null;
                return (
                  <tr key={attrKey} className={isRowIdentical(attrKey) ? 'identical-row' : 'different-row'}>
                    <th scope="row">{attrKey.replace(/_/g, ' ')}</th>
                    {products.map(p => (
                      <td key={p.id}>{p.attributes[attrKey] ?? 'N/A'}</td>
                    ))}
                  </tr>
                );
              })}
            </>
          ))}
        </tbody>
      </table>
    </div>
  );
}

对比的 URL 状态(使用 replaceState,避免污染后退按钮历史记录):

function toggleCompare(productId) {
  const params = new URLSearchParams(window.location.search);
  const current = params.getAll('compare');
  if (current.includes(productId)) {
    params.delete('compare');
    current.filter(id => id !== productId).forEach(id => params.append('compare', id));
  } else if (current.length < 4) {
    params.append('compare', productId);
  }
  window.history.replaceState({}, '', `${window.location.pathname}?${params.toString()}`);
}

最佳实践

  • 将对比商品数量限制为 2–4 件 — 超过 4 列会导致表格在大多数屏幕上布局错乱;应在 UI 中加以限制
  • 按类别对属性分组 — 将规格整理为不同分组(显示屏、性能、电池),避免形成 50 行的扁平表格
  • 提供“仅显示差异”切换选项 — 所有商品值都相同的行会造成干扰;应提供便捷的切换选项
  • 让表格在移动设备上可水平滚动 — 在外层容器上使用 overflow-x: auto;切勿为了适应小屏幕而隐藏列
  • 从商品列表页预填数据 — 顾客在 PLP 上选好商品后点击“立即对比”,应在跳转时将 ID 放入 URL
  • 统一属性命名 — 不同商品的规格必须使用完全相同的字段名称(例如,始终使用“屏幕尺寸”,不要有时使用“显示屏尺寸”),以便表格行对齐

常见问题

问题解决方案
表格在移动设备上溢出将表格放入可滚动容器;对第一列(属性标签)使用 position: sticky
部分商品缺少属性将值设为“N/A”——切勿跳过单元格,否则会导致列对齐错乱
对比栏遮挡页面内容对比栏显示时,为页面主体添加与对比栏高度相等的 padding-bottom
商品的属性集合不同统一所有待对比商品的属性键;缺失的值填为 null

相关技能

  • @product-page-design
  • @faceted-navigation
  • @accessibility-commerce
  • @recently-viewed-products

评论

支持 Markdown