用ant design 的tag来制作组件封装然后实现应该筛选功能的话,我得考虑什么,具体筛选是点击tag之后会得到对应的筛选后的信息,我的后端接口应该是放在主页面没问题,然后传类别和该类别的tag,但是tag是能选择了,那数据还是没筛选啊,听前辈说是ant design的组件有个回调函数,但是我不会用,而且这个ant design的tag组件还有自带的api之类的东西,但是我不会用,首先我该怎么实现筛选的逻辑,回调函数是干什么的,然后我怎么用自带的api。
(最好不要在不了解一段代码的前提下,修改或增加代码的逻辑)
要使用 Ant Design Design 的 Tag 组件实现筛选功能,核心是通过 **状态管理** + **Tag 交互回调** + **数据过滤/接口请求** 来完成。下面分步骤拆解逻辑、回调函数的作用及 API 使用方法:
### 一、筛选功能的核心逻辑
筛选的本质是:**用户点击 Tag 后,记录选中的筛选条件,然后根据条件过滤数据(或重新请求接口)**。
具体流程:
1. **维护选中状态**:用一个变量(如数组)存储用户当前选中的 Tag 值(例如 `selectedTags: ['电影', '音乐']`)。
2. **Tag 交互触发状态变更**:用户点击 Tag 时,通过回调函数更新选中状态(添加/移除 Tag 值)。
3. **根据状态筛选数据**:
- 若数据在前端(已获取全量数据):用 `filter` 方法根据 `selectedTags` 过滤数据。
- 若数据需要后端筛选:将 `selectedTags` 作为参数传给后端接口,重新请求数据。
### 二、Tag 组件的回调函数作用
Ant Design 的 Tag 组件(尤其是 `CheckableTag`,即“可选择标签”)的回调函数是 **用户交互与状态更新的桥梁**,核心回调如下:
| 组件 | 回调函数 | 作用 |
|--------------|----------------|----------------------------------------------------------------------|
| `Tag` | `onClose` | 当 Tag 可关闭时(设置了 `closeIcon`),点击关闭按钮触发,用于移除标签。 |
| `CheckableTag`| `onChange` | 点击 Tag 时触发(切换选中状态),返回当前是否选中(`checked: boolean`),用于更新选中状态。 |
**为什么用 `CheckableTag` 而不是普通 `Tag`?**
普通 `Tag` 更适合“展示/删除标签”,而 `CheckableTag` 自带“选中/未选中”状态切换(类似复选框),更适合筛选场景(支持多选)。
### 三、具体实现步骤(以 `CheckableTag` 为例)
假设需求:通过多个标签筛选“文章列表”,标签类别为“分类”(如电影、音乐、书籍),点击标签后显示对应分类的文章。
#### 1. 定义初始数据和状态
```jsx
import { CheckableTag } from 'antd';
import { useState, useEffect } from 'react';
const TagFilter = () => {
// 所有可选的标签(假设从后端获取或静态定义)
const allTags = ['电影', '音乐', '书籍', '体育'];
// 存储选中的标签(筛选条件)
const [selectedTags, setSelectedTags] = useState([]);
// 存储筛选后的数据(或全量数据)
const [filteredData, setFilteredData] = useState([]);
};
```
#### 2. 实现 Tag 点击的回调逻辑(`onChange`)
`CheckableTag` 的 `onChange` 会在点击时触发,返回当前标签是否被选中(`checked`)。我们需要根据这个状态更新 `selectedTags`:
```jsx
// 处理 Tag 点击事件
const handleTagChange = (tag, checked) => {
if (checked) {
// 选中:添加到 selectedTags
setSelectedTags([...selectedTags, tag]);
} else {
// 未选中:从 selectedTags 中移除
setSelectedTags(selectedTags.filter(t => t !== tag));
}
};
```
#### 3. 渲染可选择的 Tag 列表
通过 `map` 遍历所有标签,用 `CheckableTag` 渲染,并绑定 `checked` 和 `onChange`:
```jsx
// 渲染标签列表
return (
<div>
<div>筛选标签:</div>
{allTags.map(tag => (
<CheckableTag
key={tag}
checked={selectedTags.includes(tag)} // 控制是否选中(受控组件)
onChange={(checked) => handleTagChange(tag, checked)} // 点击时触发
>
{tag}
</CheckableTag>
))}
{/* 展示筛选后的数据 */}
<div>筛选结果:{JSON.stringify(filteredData)}</div>
</div>
);
```
**关键点**:`CheckableTag` 是 **受控组件**,必须通过 `checked` 属性绑定状态(`selectedTags.includes(tag)`),否则选中状态不会同步。
#### 4. 根据选中的标签筛选数据
根据 `selectedTags` 的变化,触发数据筛选(前端过滤或后端请求):
```jsx
// 监听 selectedTags 变化,触发筛选
useEffect(() => {
// 方式1:前端筛选(全量数据已获取)
const filterData = () => {
// 假设全量数据为 allData(可从 props 或接口获取)
const allData = [
{ id: 1, title: '电影推荐', category: '电影' },
{ id: 2, title: '音乐榜单', category: '音乐' },
{ id: 3, title: '书籍精读', category: '书籍' },
];
// 若没有选中标签,展示全部;否则展示包含选中标签的数据
if (selectedTags.length === 0) {
setFilteredData(allData);
} else {
setFilteredData(allData.filter(item => selectedTags.includes(item.category)));
}
};
// 方式2:调用后端接口筛选(推荐,适合大量数据)
const fetchFilteredData = async () => {
try {
const response = await fetch(`/api/data?categories=${selectedTags.join(',')}`);
const data = await response.json();
setFilteredData(data);
} catch (error) {
console.error('请求失败', error);
}
};
// 执行筛选(二选一)
filterData(); // 前端筛选
// fetchFilteredData(); // 后端筛选
}, [selectedTags]); // 当 selectedTags 变化时重新执行
```
### 四、Ant Design Tag 常用 API 说明
#### 1. 基础 `Tag` 组件(用于展示/关闭标签,较少用于筛选)
| 参数 | 说明 | 示例 |
|-------------|-------------------------------|---------------------------------------|
| `color` | 标签颜色(预设值或色值) | `<Tag color="success">成功</Tag>` |
| `closeIcon` | 自定义关闭按钮(开启可关闭) | `<Tag closeIcon={<CloseOutlined />} onClose={handleClose}>` |
| `onClose` | 关闭标签时的回调 | `(e) => { console.log('关闭标签'); }` |
#### 2. `CheckableTag` 组件(筛选核心,支持选中状态)
| 参数 | 说明 | 示例 |
|------------|-------------------------------|-------------------------------------------|
| `checked` | 是否选中(受控属性) | `checked={selectedTags.includes(tag)}` |
| `onChange` | 点击切换选中状态的回调 | `(checked) => handleTagChange(tag, checked)` |
| `icon` | 标签前的图标(>=5.27.0 支持) | `<CheckableTag icon={<MusicOutlined />}>音乐</CheckableTag>` |
### 五、完整示例代码
```jsx
import { CheckableTag } from 'antd';
import { useState, useEffect } from 'react';
import { MusicOutlined, BookOutlined, FilmOutlined, TrophyOutlined } from '@ant-design/icons';
const TagFilterExample = () => {
// 标签数据(带图标)
const tagList = [
{ key: '电影', icon: <FilmOutlined /> },
{ key: '音乐', icon: <MusicOutlined /> },
{ key: '书籍', icon: <BookOutlined /> },
{ key: '体育', icon: <TrophyOutlined /> },
];
// 选中的标签
const [selectedTags, setSelectedTags] = useState([]);
// 筛选后的数据
const [filteredData, setFilteredData] = useState([]);
// 处理标签选中状态变化
const handleTagChange = (tagKey, checked) => {
if (checked) {
setSelectedTags([...selectedTags, tagKey]);
} else {
setSelectedTags(selectedTags.filter(key => key !== tagKey));
}
};
// 模拟筛选数据
useEffect(() => {
// 模拟后端接口返回的全量数据
const mockAllData = [
{ id: 1, name: '《流浪地球》影评', category: '电影' },
{ id: 2, name: '周杰伦新专辑解析', category: '音乐' },
{ id: 3, name: '《人类简史》读书笔记', category: '书籍' },
{ id: 4, name: '世界杯赛程预测', category: '体育' },
{ id: 5, name: '经典钢琴曲推荐', category: '音乐' },
];
// 根据选中的标签筛选
const result = selectedTags.length === 0
? mockAllData
: mockAllData.filter(item => selectedTags.includes(item.category));
setFilteredData(result);
}, [selectedTags]);
return (
<div style={{ padding: 20 }}>
<h3>内容分类筛选</h3>
<div style={{ marginBottom: 20 }}>
{tagList.map(tag => (
<CheckableTag
key={tag.key}
icon={tag.icon}
checked={selectedTags.includes(tag.key)}
onChange={(checked) => handleTagChange(tag.key, checked)}
style={{ marginRight: 8, marginBottom: 8 }}
>
{tag.key}
</CheckableTag>
))}
</div>
<div>
<h4>筛选结果({filteredData.length}条)</h4>
<ul>
{filteredData.map(item => (
<li key={item.id}>{item.name}({item.category})</li>
))}
</ul>
</div>
</div>
);
};
export default TagFilterExample;
```
### 总结
1. **筛选逻辑**:通过 `selectedTags` 记录选中条件,状态变化时触发数据过滤/接口请求。
2. **回调函数**:`CheckableTag` 的 `onChange` 是核心,用于更新选中状态;`Tag` 的 `onClose` 用于移除标签(适合“已选标签列表”场景)。
3. **API 用法**:`CheckableTag` 需通过 `checked` 绑定状态,`onChange` 处理交互;可结合 `icon` 等属性增强视觉效果。
按这个思路,就能用 Ant Design 的 Tag 组件实现灵活的筛选功能了。