Allotment分割面板:无法同时实现初始尺寸与记忆上次尺寸问题
问题原因分析
你的核心问题是没有区分「首次展开面板B」和「再次展开面板B(恢复拖拽位置)」两种场景,导致默认高度设置和拖拽位置恢复的逻辑互相覆盖:
- 如果每次展开都强制设置为整体高度的1/5,之前拖拽保存的位置会被覆盖,无法实现功能2;
- 如果直接复用保存的拖拽位置,首次展开时该位置未初始化,就不会触发1/5的默认高度,无法实现功能3。
解决思路与代码调整
1. 核心改进方向
新增状态标记首次展开,同时在展开/收起时做分支处理:
- 收起时:保存当前面板B的实际高度;
- 展开时:首次展开用1/5高度,非首次展开用之前保存的高度。
2. 调整后的代码示例
import { useState, useRef } from "react"; import { Allotment } from "allotment"; import "allotment/dist/style.css"; export default function App() { const [isBCollapsed, setIsBCollapsed] = useState(true); const [savedBHeight, setSavedBHeight] = useState(null); const [isFirstExpand, setIsFirstExpand] = useState(true); const allotmentRef = useRef(null); const toggleBCollapse = () => { if (isBCollapsed) { const containerHeight = allotmentRef.current?.clientHeight || 500; let targetHeightRatio; if (isFirstExpand) { // 首次展开:设置为整体高度的1/5 targetHeightRatio = (containerHeight / 5) / containerHeight * 100; setIsFirstExpand(false); } else { // 非首次展开:恢复保存的高度占比 targetHeightRatio = (savedBHeight / containerHeight) * 100; } allotmentRef.current.setSizes([100 - targetHeightRatio, targetHeightRatio]); } else { // 收起时保存当前面板B的实际高度 const currentSizes = allotmentRef.current.getSizes(); setSavedBHeight((currentSizes[1] / 100) * allotmentRef.current.clientHeight); allotmentRef.current.setSizes([100, 0]); } setIsBCollapsed(!isBCollapsed); }; const handleSizesChange = (sizes) => { // 仅当面板B展开时,更新保存的高度 if (!isBCollapsed) { setSavedBHeight((sizes[1] / 100) * allotmentRef.current.clientHeight); } }; return ( <div style={{ height: "100vh" }}> <button onClick={toggleBCollapse}> Expand or collapse the allotment B </button> <Allotment ref={allotmentRef} vertical onChange={handleSizesChange} defaultSizes={[100, 0]} > <Allotment.Pane>A</Allotment.Pane> <Allotment.Pane>B</Allotment.Pane> </Allotment> </div> ); }
3. 关键逻辑说明
isFirstExpand状态标记首次展开,确保默认高度只在第一次生效;- 收起时通过
getSizes获取面板B的占比,转换为实际高度保存; - 展开时根据
isFirstExpand的值,选择使用默认高度或保存的高度; handleSizesChange仅在面板B展开时更新保存的高度,避免收起时的尺寸变化干扰。
内容的提问来源于stack exchange,提问作者SoftTimur
相关产品推荐
相关产品推荐

