Material-UI Accordion 折叠面板完全指南
2026/9/8 22:54:00 网站建设 项目流程

Material-UI Accordion 折叠面板完全指南

【免费下载链接】material-uiMaterial UI: Comprehensive React component library that implements Google's Material Design. Free forever.项目地址: https://gitcode.com/GitHub_Trending/ma/material-ui

Material-UI(MUI)的折叠面板 Accordion 组件,帮你把 FAQ 答案、多层级设置项、长文档目录这类内容收进可点击展开的面板里,减少页面滚动量,信息又不丢失。下面从适用场景讲到受控模式和嵌套写法,带你把它用到顺手。

一、什么时候该用 React 折叠面板 📋

适合"信息多、但用户一次只看一块"的页面,常见有三种:

  • FAQ 问答页:十几个问题平铺太长,收进面板后一屏能看完目录感;
  • 多层级设置页:如用户管理、过滤规则、个人数据,按类别分组折叠;
  • 内容目录或长文档分区:先露出小节标题,点哪看哪。

只要判断标准是"读者需要按需展开",折叠面板比手写下拉脚本省事得多,展开收起、键盘操作都由组件内置。

二、四个核心组件,一张表看懂

折叠面板是"一个容器 + 三块零件"的组合,各管一摊:

组件职责
Accordion面板容器,持有展开/折叠状态,处理点击与键盘交互
AccordionSummary标题区域,点击它触发展开或收起,展开图标也挂在它上面
AccordionDetails内容区域,包裹面板正文,可以是文本、表单等任意 React 组件
AccordionActions可选的底部操作区,用来放"重置""删除"这类按钮

四个组件必须成组使用,Accordion里至少放一个Summary和一个Details,顺序不能反。

三、最小示例:30 秒搭好一个折叠面板

最小可运行片段长这样(省略 import):

<Accordion defaultExpanded> <AccordionSummary expandIcon={<ExpandMoreIcon />}> <Typography>面板标题</Typography> </AccordionSummary> <AccordionDetails> <Typography>点击标题即可展开或折叠的内容区域</Typography> </AccordionDetails> </Accordion>

这段代码创建了一个默认展开的面板:标题右侧带一个展开图标,点击标题或图标,内容区域会带过渡动画地收起或展开。

四、三种高频定制:默认展开、换图标、禁用交互

新手最常用的三个定制点,其实都只是加一个属性,不必各写一段代码:

想要的效果做法
默认展开Accordion上加defaultExpanded,首次渲染就是展开状态
换展开图标AccordionSummaryexpandIcon传任意图标,如ArrowDownwardIcon,展开时的旋转动画由组件自动处理
禁用交互Accordion上加disabled,面板变灰且不再响应点击

另外两个常用开关也顺手记一下:square去掉圆角让它贴合列表容器,disableGutters去掉内边距让面板更紧凑。

五、受控模式:让 FAQ 页一次只展开一个面板

"手风琴"效果——点开一个、收起其余——需要把展开状态提到父组件,用expandedonChange接管:

const [expanded, setExpanded] = React.useState('panel1'); const handleChange = (panel) => (event, isExpanded) => { setExpanded(isExpanded ? panel : false); }; <Accordion expanded={expanded === 'panel1'} onChange={handleChange('panel1')}> <AccordionSummary>第一个问题</AccordionSummary> <AccordionDetails>……</AccordionDetails> </Accordion> {/* 其余面板同理,各自绑定 handleChange('panel2') 等 */}

这里用同一个状态存"当前展开的是哪块",expanded === 'panel1'这种比较让面板们互相排斥:展开新的,旧的自动收起。onChange的第二个参数isExpanded告诉你这次点击是展开还是收起,直接拿来更新状态即可。

六、进阶两件事:嵌套面板与收起时卸载内容

嵌套折叠面板用于层级化内容,写法就是在外层AccordionDetails里再放一个完整的Accordion

<Accordion defaultExpanded> <AccordionSummary> <Typography>主面板</Typography> </AccordionSummary> <AccordionDetails> <Accordion> <AccordionSummary> <Typography>嵌套面板</Typography> </AccordionSummary> <AccordionDetails> <Typography>层级化的内容</Typography> </AccordionDetails> </Accordion> </AccordionDetails> </Accordion>

注意嵌套时各层面板互不干扰,外层收起会一并隐藏子面板。

性能上有一个容易被忽略的点:默认收起的面板内容只是被视觉上藏起来,仍挂载在 DOM 里。如果面板内是图表、大表格这类重组件,建议加slotProps={{ transition: { unmountOnExit: true } }},让内容在收起时真正卸载、展开时再挂载,减少 DOM 节点和内存占用。

无障碍方面,AccordionSummary默认会自动生成aria-expanded等属性,多数场景不用手动加;如果要自定义标题结构,可以像官方示例那样给Summaryid、给Details加对应的aria-controls,保证 ARIA 无障碍语义完整。

七、常见问题速查

问:怎么只允许同时展开一个面板?答:用受控模式,把状态合并成一个变量记录当前展开的面板,各面板的expanded由它派生。

问:收起后面板内容为什么还在 DOM 里?答:这是默认行为,只是视觉隐藏。加unmountOnExit: true后收起即卸载。

问:defaultExpandedexpanded有什么区别?答:前者是"初始值",之后交给组件自己管;后者是受控的"当前值",每次变化都要靠onChange回写,二者不要同时用。

问:想去掉圆角、内边距,让面板贴边排列?答:分别加squaredisableGutters两个属性,多面板纵向排列时视觉更整齐。

延伸阅读

  • 官方文档:accordion.md
  • 受控示例源码:ControlledAccordions.tsx
  • 组件源码目录:packages/mui-material/src/Accordion/

把场景选好、状态想清楚,Material-UI 的折叠面板就能覆盖你绝大多数"内容收纳"需求。

【免费下载链接】material-uiMaterial UI: Comprehensive React component library that implements Google's Material Design. Free forever.项目地址: https://gitcode.com/GitHub_Trending/ma/material-ui

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询