如何通过location.hash打开指定Material UI折叠面板并支持多面板展开?
实现Material UI Accordion通过Hash定位并支持多面板展开
核心思路
原来的实现用单个字符串存储展开状态,同一时间只能匹配一个面板,所以无法支持多面板展开。改为用数组存储所有展开的面板ID,就能同时控制多个面板的展开/收起状态,同时初始化时读取location.hash自动展开对应面板。
具体实现步骤
修改状态为数组
初始化时读取当前页面的location.hash,去掉开头的#后作为初始展开的面板ID存入数组:const [expandedPanels, setExpandedPanels] = React.useState(() => { const targetPanelId = window.location.hash.slice(1); return targetPanelId ? [targetPanelId] : []; });调整Accordion的expanded属性
先统一处理面板ID,再判断当前ID是否在展开数组中:{categories.map((category, index) => { const panelId = category.key.replace(/\s+/g, '-').toLowerCase(); return ( <Accordion key={index} elevation={1} expanded={expandedPanels.includes(panelId)} className="filter-items-accordion" id={panelId} onChange={() => togglePanel(panelId)} > {/* 这里放置AccordionSummary和AccordionDetails内容 */} </Accordion> ); })}实现面板切换函数
点击面板时,切换该ID在展开数组中的存在状态(已展开则移除,未展开则添加):const togglePanel = (panelId) => { setExpandedPanels(prevPanels => { if (prevPanels.includes(panelId)) { return prevPanels.filter(id => id !== panelId); } else { return [...prevPanels, panelId]; } }); };可选:监听Hash变化
如果需要用户手动修改URL中的hash时自动展开对应面板,添加监听逻辑:React.useEffect(() => { const handleHashUpdate = () => { const newPanelId = window.location.hash.slice(1); if (newPanelId && !expandedPanels.includes(newPanelId)) { setExpandedPanels(prev => [...prev, newPanelId]); } }; window.addEventListener('hashchange', handleHashUpdate); return () => window.removeEventListener('hashchange', handleHashUpdate); }, [expandedPanels]);
效果说明
- 页面加载时,如果URL带有
#panel-1这类hash,对应的面板会自动展开 - 点击任意面板可以独立展开/收起,支持同时展开多个面板
- 修改URL的hash后,对应的面板会自动加入展开列表
内容的提问来源于stack exchange,提问作者Paul VI
相关产品推荐
相关产品推荐

