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

如何自定义Material UI Accordion:修复分隔线与切换折叠图标

自定义Material UI Accordion 问题解决方案

1. 修复分隔线样式(显示最后一项分隔线+加粗)

MUI 默认会隐藏最后一个 Accordion 的分隔线,同时默认分隔线较细。可以通过自定义样式强制所有项(包括最后一项)显示加粗分隔线,两种实现方式:

方式一:使用 styled 组件封装

import { styled } from '@mui/material/styles';
import Accordion from '@mui/material/Accordion';

const StyledAccordion = styled(Accordion)(({ theme }) => ({
  // 覆盖默认分隔线逻辑,统一自定义样式
  '&:not(:last-child)': { borderBottom: 'none' },
  borderBottom: '2px solid #e0e0e0', // 加粗分隔线,颜色可自行调整
  '&:last-child': { borderBottom: '2px solid #e0e0e0' }, // 强制最后一项显示分隔线
}));

之后直接使用 <StyledAccordion> 替代原生 <Accordion> 即可。

方式二:直接通过 sx 属性设置

<Accordion 
  sx={{
    borderBottom: '2px solid #e0e0e0',
    '&:last-child': { borderBottom: '2px solid #e0e0e0' },
    '&:not(:last-child)': { borderBottom: '2px solid #e0e0e0' }
  }}
>
  {/* 内容 */}
</Accordion>

2. 解决展开/收起状态切换图标(修复"Cannot find name 'expanded'"错误)

错误原因是未正确声明和管理展开状态的变量,需要用 React useState 跟踪状态,分单个/多个 Accordion 场景处理:

单个 Accordion 场景

import { useState } from 'react';
import AddCircleIcon from '@mui/icons-material/AddCircle';
import RemoveCircleIcon from '@mui/icons-material/RemoveCircle';
import Accordion from '@mui/material/Accordion';
import AccordionSummary from '@mui/material/AccordionSummary';

// 声明展开状态变量
const [expanded, setExpanded] = useState(false);

// 使用时绑定状态与图标
<StyledAccordion
  expanded={expanded}
  onChange={() => setExpanded(!expanded)}
>
  <AccordionSummary
    expandIcon={expanded ? <RemoveCircleIcon /> : <AddCircleIcon />}
  >
    {/* 摘要内容 */}
  </AccordionSummary>
  {/* 详情内容 */}
</StyledAccordion>

多个 Accordion 场景(通过 ID 区分面板)

import { useState } from 'react';
import AddCircleIcon from '@mui/icons-material/AddCircle';
import RemoveCircleIcon from '@mui/icons-material/RemoveCircle';

// 用字符串跟踪当前展开的面板ID,默认无展开项
const [expanded, setExpanded] = useState<string | false>(false);

// 遍历渲染面板
{yourDataList.map(item => (
  <StyledAccordion
    key={item.id}
    expanded={expanded === item.id}
    onChange={(e, isExpanded) => setExpanded(isExpanded ? item.id : false)}
  >
    <AccordionSummary
      expandIcon={expanded === item.id ? <RemoveCircleIcon /> : <AddCircleIcon />}
    >
      {item.title}
    </AccordionSummary>
    {/* 详情内容 */}
  </StyledAccordion>
))}

3. Material UI Accordion 样式类定制指导

MUI Accordion 提供了层级化的样式类,可通过 styled 组件、sx 属性或全局主题三种方式定制,核心样式类说明:

组件核心样式类作用
Accordionroot/expanded/rounded根容器/展开状态/圆角样式
AccordionSummaryroot/expanded/content/expandIcon摘要容器/展开状态/内容区/图标容器
AccordionDetailsroot详情内容容器

定制示例

1. 用 styled 深度定制摘要栏

import { styled } from '@mui/material/styles';
import AccordionSummary from '@mui/material/AccordionSummary';

const CustomAccordionSummary = styled(AccordionSummary)(({ theme }) => ({
  backgroundColor: theme.palette.grey[50],
  '&.Mui-expanded': { minHeight: '64px' }, // 展开时的最小高度
  '& .MuiAccordionSummary-content': { margin: '12px 0' }, // 内容上下间距
  '& .MuiAccordionSummary-expandIcon': { color: theme.palette.primary.main }, // 图标颜色
}));

2. 用 sx 快速调整单个组件样式

<AccordionSummary
  sx={{
    bgcolor: 'grey.50',
    '&.Mui-expanded': { minHeight: '64px' },
    '& .MuiAccordionSummary-content': { my: 1.5 },
    '& .MuiAccordionSummary-expandIcon': { color: 'primary.main' }
  }}
>
  {/* 内容 */}
</AccordionSummary>

3. 全局主题统一覆盖所有 Accordion

import { createTheme, ThemeProvider } from '@mui/material/styles';

const theme = createTheme({
  components: {
    MuiAccordion: {
      styleOverrides: {
        root: {
          borderBottom: '2px solid #e0e0e0',
          '&:last-child': { borderBottom: '2px solid #e0e0e0' },
        },
        expanded: { margin: '0 !important' }, // 去掉展开时的上下间距
      },
    },
  },
});

// 在父组件中包裹应用
<ThemeProvider theme={theme}>
  {/* 你的Accordion组件 */}
</ThemeProvider>

内容的提问来源于stack exchange,提问作者Ralph Henry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 08:03:33