CollectionShelves 筛选货架
产品筛选货架组件,支持多条件筛选和产品展示
组件信息
- 组件名称: CollectionShelves (筛选货架)
- 所属分类: 货架模块
- 状态: 🔄 开发完成
- Figma 设计稿: 查看设计稿
功能特性
- ✅ 多维度筛选: 支持多个筛选条件组合(品类、价格、功能等)
- ✅ 产品卡片网格: 响应式产品网格展示,自动调整列数
- ✅ 响应式布局: 移动端 1-2 列,桌面端 3-4 列
- ✅ 加载状态: 加载中骨架屏提示
- ✅ 空状态展示: 无筛选结果时友好提示
- ✅ 筛选联动: 筛选条件变更自动更新产品列表
- ✅ URL 同步: 筛选参数可同步到 URL (可选)
- ✅ 分页支持: 大量产品时支持分页加载
使用示例
示例 1: 基础筛选货架
import { CollectionShelves } from '@anker-in/headless-ui/biz'
export default function Page() {
return (
<CollectionShelves
data={{
filters: [
{
name: '品类',
key: 'category',
options: ['充电器', '充电宝', '数据线']
},
{
name: '功率',
key: 'power',
options: ['20W', '30W', '65W', '100W']
}
],
products: [
{
id: '001',
name: 'Anker 737 充电器',
price: 99.99,
image: {
url: 'https://images.unsplash.com/photo-1593642632559-0c6d3fc62b89',
alt: 'Anker 737'
},
category: '充电器',
power: '100W'
},
{
id: '002',
name: 'Anker PowerCore 充电宝',
price: 59.99,
image: {
url: 'https://images.unsplash.com/photo-1581578731548-c64695cc6952',
alt: 'PowerCore'
},
category: '充电宝',
power: '65W'
}
]
}}
/>
)
}示例 2: 带价格范围筛选
<CollectionShelves
data={{
filters: [
{
name: '价格区间',
key: 'priceRange',
type: 'range',
min: 0,
max: 200,
step: 10
},
{
name: '品牌',
key: 'brand',
options: ['Anker', 'eufy', 'Soundcore']
}
],
products: productsData,
onFilterChange: (selectedFilters) => {
console.log('筛选条件变更:', selectedFilters)
}
}}
/>示例 3: 加载状态
const [loading, setLoading] = useState(true)
const [products, setProducts] = useState([])
<CollectionShelves
data={{
filters: filtersData,
products: products,
loading: loading
}}
/>示例 4: 空状态展示
<CollectionShelves
data={{
filters: filtersData,
products: [], // 空产品列表
emptyState: {
title: '未找到匹配的产品',
description: '尝试调整筛选条件',
image: {
url: 'https://example.com/empty-state.svg',
alt: '空状态'
}
}
}}
/>Props API
CollectionShelvesProps
| 属性 | 类型 | 默认值 | 必需 | 说明 |
|---|---|---|---|---|
| data | CollectionShelvesData | - | ✅ | 货架数据配置 |
| className | string | ” | - | 自定义类名 |
CollectionShelvesData
| 字段 | 类型 | 默认值 | 必需 | 说明 |
|---|---|---|---|---|
| filters | FilterGroup[] | - | ✅ | 筛选条件组 |
| products | Product[] | - | ✅ | 产品列表 |
| onFilterChange | (filters: SelectedFilters) => void | - | - | 筛选变更回调 |
| loading | boolean | false | - | 加载状态 |
| emptyState | EmptyStateConfig | - | - | 空状态配置 |
| gridColumns | number | 4 | - | 桌面端网格列数 |
FilterGroup
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
| name | string | ✅ | 筛选组名称 |
| key | string | ✅ | 筛选组键值 |
| type | ’checkbox’ | ‘range’ | - | 筛选类型 |
| options | string[] | - | 选项列表(checkbox 类型) |
| min | number | - | 最小值(range 类型) |
| max | number | - | 最大值(range 类型) |
Product
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
| id | string | ✅ | 产品 ID |
| name | string | ✅ | 产品名称 |
| price | number | ✅ | 产品价格 |
| image | Img | ✅ | 产品图片 |
| [key] | any | - | 其他筛选字段 |
响应式行为
网格布局
| 断点 | 屏幕宽度 | 列数 | 卡片间距 |
|---|---|---|---|
| Mobile | < 768px | 1-2 列 | 12px |
| Tablet | ≥ 768px | 2-3 列 | 16px |
| Laptop | ≥ 1025px | 3-4 列 | 20px |
| Desktop | ≥ 1440px | 4 列 | 24px |
筛选器位置
- 移动端: 筛选器折叠在顶部,点击展开
- 桌面端: 筛选器固定在左侧侧边栏
常见问题 (FAQ)
1. 如何实现筛选条件联动?
通过 onFilterChange 回调处理:
const handleFilterChange = (selectedFilters) => {
// 根据筛选条件过滤产品
const filtered = allProducts.filter(product => {
return selectedFilters.category.includes(product.category) &&
product.price >= selectedFilters.priceRange.min &&
product.price <= selectedFilters.priceRange.max
})
setProducts(filtered)
}
<CollectionShelves
data={{
filters: filtersData,
products: products,
onFilterChange: handleFilterChange
}}
/>2. 如何自定义网格列数?
使用 gridColumns 字段:
<CollectionShelves
data={{
filters: filtersData,
products: productsData,
gridColumns: 3 // 桌面端 3 列
}}
/>3. 产品卡片样式可以自定义吗?
可以通过 className 覆盖:
<CollectionShelves
data={{...}}
className="[&_.product-card]:shadow-lg [&_.product-card]:rounded-2xl"
/>4. 如何处理大量产品的性能问题?
方案 1: 使用虚拟滚动
import { VirtualList } from 'react-window'
// 结合 VirtualList 优化长列表渲染方案 2: 使用分页
<CollectionShelves
data={{
filters: filtersData,
products: currentPageProducts,
pagination: {
currentPage: 1,
totalPages: 10,
onPageChange: handlePageChange
}
}}
/>5. 筛选器可以默认展开吗?
在移动端,筛选器默认折叠。如需默认展开:
<CollectionShelves
data={{
filters: filtersData,
products: productsData,
defaultFilterExpanded: true // 默认展开
}}
/>6. 如何实现 URL 同步筛选参数?
使用 React Router 或 Next.js Router:
import { useSearchParams } from 'next/navigation'
import scenarios from './scenarios.json'
const searchParams = useSearchParams()
const handleFilterChange = (filters) => {
const params = new URLSearchParams(searchParams)
params.set('filters', JSON.stringify(filters))
router.push(`?${params.toString()}`)
}7. 空状态可以自定义吗?
可以,通过 emptyState 字段:
<CollectionShelves
data={{
filters: filtersData,
products: [],
emptyState: {
title: '暂无符合条件的产品',
description: '试试其他筛选条件吧',
image: {
url: '/empty-box.svg',
alt: '空状态'
},
cta: {
text: '查看全部产品',
link: '/products'
}
}
}}
/>应用场景
场景 1: 品类筛选页
- 用户按品类、价格、功能筛选产品
- 实时更新产品列表
- 支持多条件组合筛选
场景 2: Collection 页面
- 展示特定品类的所有产品
- 提供筛选功能帮助用户找到目标产品
- 集成 SEO 优化的 URL 参数
场景 3: 搜索结果页
- 展示搜索结果
- 通过筛选器细化结果
- 显示结果数量
相关组件
- ShelfDisplay - 常规货架1
- CollectionBanner - Collection Banner
Last updated on