如何实现鼠标悬停时自动展开Material UI Accordion折叠面板
解决方案
问题根因
- 你当前绑定的
handleChange是为MUI原生onChange事件设计的,该事件会主动传入第二个参数newExpanded标识切换后的状态,但鼠标事件(onMouseOver/onMouseEnter/onMouseMove)不会传递这个参数,导致newExpanded恒为undefined,最终执行setExpanded(false),所以每次触发都会关闭面板 - 单纯用CSS
:hover无法控制展开状态,因为MUI Accordion的展开是受控于expanded属性的React状态,仅靠CSS无法修改状态值
修复步骤
- 替换事件处理逻辑,移除原本适配点击事件的判断逻辑,悬停时直接将当前面板设为展开状态
- 将绑定的
onMouseMove替换为onMouseEnter,避免鼠标移动时重复触发事件 - 可按需添加
onMouseLeave事件实现鼠标移出后自动收起
修复后代码
const Accordion = withStyles({ root: { border: '1px solid rgba(0, 0, 0, .125)', boxShadow: 'none', '&:not(:last-child)': { borderBottom: 0, }, '&:before': { display: 'none', }, '&$expanded': { margin: 'auto', }, }, expanded: {}, })(MuiAccordion); const AccordionSummary = withStyles({ root: { backgroundColor: 'rgba(0, 0, 0, 0)', borderBottom: '1px solid rgba(0, 0, 0, .125)', marginBottom: -1, minHeight: 30, '&$expanded': { minHeight: 30, }, }, content: { '&$expanded': { margin: '12px 0', }, }, expanded: {}, })(MuiAccordionSummary); const AccordionDetails = withStyles((theme) => ({ root: { padding: theme.spacing(2), }, }))(MuiAccordionDetails); export default function CategoryList(props) { const [expanded, setExpanded] = React.useState('panel1'); // 鼠标进入时直接展开当前面板 const handleMouseEnter = (panel) => () => { setExpanded(panel); }; // 按需添加:鼠标移出时收起面板,如果需要保持最后悬停的面板展开可删除该方法和对应绑定 const handleMouseLeave = () => { setExpanded(false); }; return ( <div> {props.categories.map(category => <Accordion square expanded={expanded === category.label} onMouseEnter={handleMouseEnter(category.label)} onMouseLeave={handleMouseLeave} > <AccordionSummary expandIcon={<ExpandMoreIcon fontSize="small"/>} aria-controls="panel1d-content" id="panel1d-header"> <Typography>{category.label}</Typography> </AccordionSummary> <AccordionDetails> <CategoryItem category={category}/> </AccordionDetails> </Accordion> )} </div> ); }
内容的提问来源于stack exchange,提问作者pawaelus
相关产品推荐
相关产品推荐

