react结合antd实现sku
实现 React 与 Ant Design 结合的 SKU 功能
数据结构设计
SKU(Stock Keeping Unit)需要明确商品属性和组合关系。通常采用以下结构:
- attributes: 商品属性(如颜色、尺寸)
- skus: 具体 SKU 组合(如红色+XL)
示例数据结构:
const data = {
attributes: [
{ name: '颜色', values: ['红色', '蓝色'] },
{ name: '尺寸', values: ['S', 'XL'] }
],
skus: [
{ id: 1, attributes: { 颜色: '红色', 尺寸: 'S' }, stock: 10, price: 99 },
{ id: 2, attributes: { 颜色: '蓝色', 尺寸: 'XL' }, stock: 5, price: 129 }
]
}
属性选择器实现
使用 Ant Design 的 Radio 或 Select 组件构建属性选择器:
import { Radio, Card } from 'antd';
function AttributeSelector({ attributes, selected, onChange }) {
return (
<Card title="商品规格">
{attributes.map(attr => (
<div key={attr.name}>
<h4>{attr.name}</h4>
<Radio.Group
value={selected[attr.name]}
onChange={e => onChange(attr.name, e.target.value)}
>
{attr.values.map(value => (
<Radio.Button key={value} value={value}>
{value}
</Radio.Button>
))}
</Radio.Group>
</div>
))}
</Card>
);
}
SKU 匹配逻辑
当用户选择属性后,需要匹配对应的 SKU:
function findMatchedSku(selected, skus) {
return skus.find(sku =>
Object.entries(selected).every(
([name, value]) => sku.attributes[name] === value
)
);
}
完整组件示例
import React, { useState } from 'react';
import { Card, Radio, Button, Tag, Divider } from 'antd';
function SkuSelector({ data }) {
const [selected, setSelected] = useState({});
const matchedSku = findMatchedSku(selected, data.skus);
const handleAttributeChange = (name, value) => {
setSelected(prev => ({ ...prev, [name]: value }));
};
return (
<div>
<AttributeSelector
attributes={data.attributes}
selected={selected}
onChange={handleAttributeChange}
/>
<Divider />
{matchedSku ? (
<div>
<Tag color="green">库存: {matchedSku.stock}</Tag>
<Tag color="orange">价格: ¥{matchedSku.price}</Tag>
<Button type="primary">加入购物车</Button>
</div>
) : (
<Tag color="red">请选择完整规格</Tag>
)}
</div>
);
}
禁用无库存选项
为提升用户体验,可以禁用无库存的属性组合:
function getDisabledValues(attributes, skus, currentSelected) {
const disabledValues = {};
attributes.forEach(attr => {
disabledValues[attr.name] = attr.values.filter(value => {
const testSelection = { ...currentSelected, [attr.name]: value };
return !skus.some(sku =>
Object.entries(testSelection).every(
([name, val]) => sku.attributes[name] === val
)
);
});
});
return disabledValues;
}
样式优化
使用 Ant Design 的 Grid 和 Space 组件优化布局:
import { Row, Col, Space } from 'antd';
// 在 AttributeSelector 中替换布局
<Row gutter={[16, 16]}>
{attributes.map(attr => (
<Col span={24} key={attr.name}>
<Space direction="vertical">
<h4>{attr.name}</h4>
<Radio.Group>
{/* ... */}
</Radio.Group>
</Space>
</Col>
))}
</Row>
价格区间显示
当存在多个 SKU 时,可以显示价格区间:
function getPriceRange(skus) {
const prices = skus.map(sku => sku.price);
return {
min: Math.min(...prices),
max: Math.max(...prices)
};
}
响应式处理
针对移动端优化显示:
import { useBreakpoint } from 'antd';
function ResponsiveSku() {
const screens = useBreakpoint();
const isMobile = !screens.md;
return (
<Radio.Group size={isMobile ? 'small' : 'middle'}>
{/* ... */}
</Radio.Group>
);
}






