You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ReactJS中使用Material UI芯片选择器筛选卡片?

ReactJS + Material UI 芯片选择器实现标签筛选卡片功能

1. 基础准备与数据结构

首先定义卡片数据,每个卡片包含用于筛选的标签数组:

const cardData = [
  { id: 1, title: "React 入门教程", tags: ["react", "frontend", "beginner"] },
  { id: 2, title: "Material UI 组件详解", tags: ["mui", "frontend", "ui"] },
  { id: 3, title: "Node.js 后端实战", tags: ["nodejs", "backend", "api"] },
  { id: 4, title: "全栈项目实战", tags: ["react", "nodejs", "fullstack"] },
];

// 提取所有唯一标签作为选择器选项
const allTags = [...new Set(cardData.flatMap(card => card.tags))];

2. 实现芯片选择器

使用Material UI的Select组件开启multiple模式,通过renderValue将选中标签渲染为芯片:

import { useState } from "react";
import { Select, MenuItem, Chip, Box, Typography, Card, CardContent } from "@mui/material";

function TagFilteredCards() {
  const [selectedTags, setSelectedTags] = useState([]);

  // 处理标签选择变更
  const handleTagChange = (event) => {
    setSelectedTags(event.target.value);
  };

  // 自定义选中标签的渲染样式
  const renderSelectedTags = (selected) => (
    <Box sx={{ display: "flex", flexWrap: "wrap", gap: 0.5 }}>
      {selected.map((tag) => (
        <Chip key={tag} label={tag} />
      ))}
    </Box>
  );

3. 实现筛选逻辑

根据选中标签过滤卡片,提供两种常用逻辑:

  • 任意匹配:卡片包含至少一个选中标签即显示
  • 全匹配:卡片必须包含所有选中标签才显示
// 筛选卡片 - 任意匹配逻辑
  const filteredCards = selectedTags.length === 0 
    ? cardData 
    : cardData.filter(card => 
        selectedTags.some(tag => card.tags.includes(tag))
      );

  // 若需要全匹配逻辑,替换为以下代码:
  // const filteredCards = selectedTags.length === 0 
  //   ? cardData 
  //   : cardData.filter(card => 
  //       selectedTags.every(tag => card.tags.includes(tag))
  //     );

4. 渲染筛选结果

最后渲染选择器和筛选后的卡片列表:

return (
    <Box sx={{ padding: 3, maxWidth: 800, margin: "0 auto" }}>
      <Typography variant="h6" gutterBottom>
        选择标签筛选卡片
      </Typography>
      <Select
        multiple
        value={selectedTags}
        onChange={handleTagChange}
        renderValue={renderSelectedTags}
        sx={{ width: "100%", marginBottom: 3 }}
        displayEmpty
      >
        {allTags.map((tag) => (
          <MenuItem key={tag} value={tag}>
            {tag}
          </MenuItem>
        ))}
      </Select>

      <Box sx={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(250px, 1fr))", gap: 2 }}>
        {filteredCards.map((card) => (
          <Card key={card.id}>
            <CardContent>
              <Typography variant="h6">{card.title}</Typography>
              <Box sx={{ marginTop: 1, display: "flex", flexWrap: "wrap", gap: 0.5 }}>
                {card.tags.map((tag) => (
                  <Chip key={tag} label={tag} size="small" />
                ))}
              </Box>
            </CardContent>
          </Card>
        ))}
      </Box>
    </Box>
  );
}

export default TagFilteredCards;

关键细节说明

  • renderValue 属性用于自定义选中值的展示,这里直接渲染为Material UI芯片
  • displayEmpty 属性允许选择器在未选中任何标签时显示占位状态
  • 可根据业务需求切换some(任意匹配)或every(全匹配)逻辑

内容的提问来源于stack exchange,提问作者Aman Shukla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 00:35:32