react-resize-demo
v4.1.0
Published
A React component library demo
Readme
react-resize-demo
一个现代化的 React 可调整大小面板组件库,支持水平和垂直方向的布局调整,具备完整的 TypeScript 支持和模块化架构。
源码地址: https://gitee.com/zugechen/react-resize-demo
✨ 特性
- ✅ 多种策略:提供 2 种 resize 策略(Basic、Flex),适应不同场景
- ✅ 双向布局:支持水平和垂直方向的布局
- ✅ 拖拽调整:可拖拽调整相邻面板的宽度/高度
- ✅ 自定义拖拽器:支持完全自定义拖拽器的外观和交互效果
- ✅ 最小尺寸:支持设置面板最小尺寸限制
- ✅ 级联调整:当面板达到最小值时,自动从相邻面板获取空间
- ✅ 虚拟化拖拽:支持虚拟节点模式,拖拽时创建虚拟框架,提升性能
- ✅ 性能优化:RAF 优化、基于位置的计算、面板变化通知、自动冻结等多项性能优化
- ✅ 可配置化:Flex 策略支持自定义计算参数,适应特殊场景
- ✅ TypeScript:完整的 TypeScript 类型支持
- ✅ 模块化架构:按策略分类的清晰目录结构,支持按需导入
- ✅ Tree-shaking:支持 Tree-shaking,减少打包体积
- ✅ 代码压缩:自动压缩代码,优化打包体积
📦 安装
npm install react-resize-demo
# 或
yarn add react-resize-demo
# 或
pnpm add react-resize-demo🚀 快速开始
基础用法(推荐使用 Flex 策略)
import { ResizePanelGroupFlex, ResizePanelFlex } from 'react-resize-demo';
function App() {
return (
<div style={{ width: '100%', height: '500px' }}>
<ResizePanelGroupFlex direction="horizontal">
<ResizePanelFlex minSize={100}>
<div>Panel 1</div>
</ResizePanelFlex>
<ResizePanelFlex minSize={200}>
<div>Panel 2</div>
</ResizePanelFlex>
<ResizePanelFlex minSize={300}>
<div>Panel 3</div>
</ResizePanelFlex>
</ResizePanelGroupFlex>
</div>
);
}其他策略
项目提供 2 种策略,可根据场景选择:
- Basic 策略:适合面板数量较少的简单场景
- Flex 策略:适合需要精确控制占比的场景(推荐)
详细对比请查看 策略对比文档
垂直布局
<ResizePanelGroupFlex direction="vertical" style={{ height: '500px' }}>
<ResizePanelFlex minSize={100}>
<div>顶部面板</div>
</ResizePanelFlex>
<ResizePanelFlex minSize={200}>
<div>中间面板</div>
</ResizePanelFlex>
<ResizePanelFlex minSize={100}>
<div>底部面板</div>
</ResizePanelFlex>
</ResizePanelGroupFlex>虚拟化模式
虚拟化模式可以在拖拽时创建虚拟节点框架,拖拽过程中只更新虚拟节点,拖拽结束后再应用到真实节点。这可以提升性能,特别是在处理复杂内容的面板时。
// 启用虚拟化(使用默认样式)
<ResizePanelGroupFlex virtual={true}>
<ResizePanelFlex minSize={100}>
<div>Panel 1</div>
</ResizePanelFlex>
<ResizePanelFlex minSize={200}>
<div>Panel 2</div>
</ResizePanelFlex>
</ResizePanelGroupFlex>
// 启用虚拟化 + 面板变化通知(推荐)
<ResizePanelGroupFlex
virtual={true}
virtualConfig={{
style: {
opacity: 0.5,
border: '2px dashed blue',
backgroundColor: 'rgba(0, 123, 255, 0.1)'
},
className: 'custom-virtual-node'
}}
onPanelsChange={(changedIndices) => {
console.log('变化的面板:', Array.from(changedIndices));
// 只重新渲染变化的面板,提升性能
}}
>
<ResizePanelFlex minSize={100}>
<div>Panel 1</div>
</ResizePanelFlex>
<ResizePanelFlex minSize={200}>
<div>Panel 2</div>
</ResizePanelFlex>
</ResizePanelGroupFlex>自定义拖拽器
所有策略都支持通过 renderHandle prop 自定义拖拽器的外观和内容:
<ResizePanelGroupFlex
renderHandle={({ prePanelIndex, nextPanelIndex, direction, isResizing }) => (
<div
className="custom-resize-handle"
style={{
width: '100%',
height: '100%',
backgroundColor: isResizing ? '#0066cc' : '#cccccc',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
transition: 'background-color 0.2s',
}}
>
<div style={{ fontSize: '12px', color: '#fff' }}>||</div>
</div>
)}
>
<ResizePanelFlex minSize={100}>
<div>Panel 1</div>
</ResizePanelFlex>
<ResizePanelFlex minSize={200}>
<div>Panel 2</div>
</ResizePanelFlex>
</ResizePanelGroupFlex>参数说明:
prePanelIndex: 前一个面板的索引nextPanelIndex: 后一个面板的索引direction: 布局方向('horizontal' | 'vertical')isResizing: 是否正在拖拽(可用于动态改变样式)
高级配置(Flex 策略)
对于 Flex 策略,你可以通过 flexConfig 自定义计算参数,以适应特殊场景:
<ResizePanelGroupFlex
flexConfig={{
minDeltaThreshold: 0.2, // 自定义最小拖拽变化阈值
sizeChangeThreshold: 0.15, // 自定义尺寸变化阈值
growChangeThreshold: 0.0002, // 自定义 grow 值变化阈值
growNormalizeBase: 200, // 自定义归一化基数
growPrecisionMultiplier: 2000, // 自定义精度倍数
flexGrowPrecisionMultiplier: 200, // 自定义 flex-grow 精度
}}
>
<ResizePanelFlex minSize={100}>
<div>Panel 1</div>
</ResizePanelFlex>
<ResizePanelFlex minSize={200}>
<div>Panel 2</div>
</ResizePanelFlex>
</ResizePanelGroupFlex>按需导入
支持分层导入,实现更好的 Tree-shaking:
// 从主入口导入(推荐)
import { ResizePanelGroupFlex, ResizePanelFlex } from 'react-resize-demo';
// 按需导入组件
import { ResizePanelGroupFlex } from 'react-resize-demo/components';
// 导入类型
import type { VirtualConfig, ResizeDirection, FlexStrategyConfig } from 'react-resize-demo/types';🎮 运行 Demo
要查看和体验完整的 demo 示例(包括虚拟化模式、性能对比等),请从源码运行:
步骤
- Clone 源码仓库
git clone https://gitee.com/zugechen/react-resize-demo.git
cd react-resize-demo- 安装依赖
npm install
# 或
pnpm install- 启动 Demo
npm run demo这将启动一个开发服务器(默认端口 3000),你可以在浏览器中查看和测试所有功能示例。
Demo 包含的内容
- ✅ 基础用法示例(水平/垂直布局)
- ✅ 虚拟化模式演示
- ✅ 性能对比测试
- ✅ 复杂内容场景演示
📖 API 文档
ResizePanelGroupFlex(推荐)
面板组容器组件,用于包裹多个 ResizePanelFlex。
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| direction | 'horizontal' \| 'vertical' | 'horizontal' | 布局方向 |
| virtual | boolean | false | 是否启用虚拟化模式 |
| virtualConfig | VirtualConfig | {} | 虚拟化配置(仅在 virtual=true 时生效) |
| style | React.CSSProperties | - | 自定义样式 |
| onPanelsChange | (changedIndices: Set<number>) => void | - | 面板变化回调,用于性能优化 |
| flexConfig | FlexStrategyConfig | - | Flex 策略配置(高级用法) |
| renderHandle | (props: ResizeHandleRenderProps) => React.ReactNode | - | 自定义拖拽器渲染函数 |
| children | React.ReactNode | - | 子元素(通常是多个 ResizePanelFlexLinked) |
VirtualConfig
虚拟化配置对象:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| enabled | boolean | false | 是否启用虚拟化(通常通过 virtual prop 设置) |
| style | React.CSSProperties | - | 虚拟节点的自定义样式 |
| className | string | - | 虚拟节点的自定义类名 |
ResizeHandleRenderProps(自定义拖拽器参数)
自定义拖拽器渲染函数的参数类型:
| 属性 | 类型 | 说明 |
|------|------|------|
| prePanelIndex | number | 前一个面板的索引 |
| nextPanelIndex | number | 后一个面板的索引 |
| direction | 'horizontal' \| 'vertical' | 布局方向 |
| isResizing | boolean | 是否正在拖拽(可用于动态改变样式) |
FlexStrategyConfig(高级配置)
Flex 策略的计算参数配置,用于精细调整计算行为:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| minDeltaThreshold | number | 0.1 | 最小拖拽变化阈值(像素),小于此值的变化将被忽略 |
| sizeChangeThreshold | number | 0.1 | 尺寸变化误差阈值(像素),用于判断面板尺寸是否发生变化 |
| growChangeThreshold | number | 0.0001 | flex-grow 值变化阈值,用于判断 grow 值是否发生变化 |
| growNormalizeBase | number | 100 | grow 值归一化基数,用于计算初始 grow 值 |
| growPrecisionMultiplier | number | 1000 | grow 值精度倍数,用于保留小数位数(1000 表示保留3位小数) |
| flexGrowPrecisionMultiplier | number | 100 | flex-grow 精度倍数,用于设置 flex-grow 时的精度(100 表示保留2位小数) |
ResizePanelFlex
可调整大小的面板组件。
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| minSize | number | 100 | 面板最小尺寸(像素) |
| children | React.ReactNode | - | 面板内容 |
🏗️ 项目结构
项目采用模块化架构,按策略分类组织代码,支持按需导入和 Tree-shaking。核心功能包括面板管理、虚拟节点管理、节流优化等工具模块,所有策略共享这些核心工具。
详细的项目结构说明请查看 PROJECT_STRUCTURE.md
🔧 开发
安装依赖
npm install
# 或
pnpm install构建库
npm run build运行 Demo(开发模式)
npm run demo这将启动一个开发服务器,你可以在浏览器中查看和测试组件。
构建 Demo(生产模式)
npm run demo:build类型检查
npm run type-check代码检查
npm run lint监听模式构建
npm run build:watch💡 工作原理
组件通过拖拽器来调整相邻面板的尺寸。拖拽器会自动插入到相邻面板之间,无需手动添加。
拖拽行为:
- 向右拖拽:扩大左侧面板,缩小右侧面板。如果右侧面板达到最小值,会自动从后续面板获取空间(级联调整)
- 向左拖拽:缩小左侧面板,扩大右侧面板。如果左侧面板达到最小值,会自动从前面面板获取空间(级联调整)
虚拟化模式: 当启用虚拟化模式时,拖拽过程中会创建虚拟节点框架来显示调整效果,真实节点保持不变。拖拽结束后再将最终尺寸应用到真实节点。这种方式可以显著提升性能,特别是在处理复杂内容的面板时。
性能优化机制:
- 使用
requestAnimationFrame与浏览器渲染同步,每帧计算一次 - 基于初始状态计算,避免累积误差
- 只更新变化的面板,未变化的面板自动冻结
- 支持面板变化通知,只重新渲染变化的面板
🔄 迁移指南
从 2.x 升级到 3.0
3.0 版本引入了策略分类架构,推荐使用 Flex 策略:
// 2.x 版本(仍然可用,向后兼容)
import { ResizePanelGroup, ResizePanel } from 'react-resize-demo';
// 3.0 版本(推荐)
import { ResizePanelGroupFlex, ResizePanelFlex } from 'react-resize-demo';新功能
3.0 版本新增了多种策略和性能优化:
// 使用 Flex 策略(推荐,性能最佳)
import { ResizePanelGroupFlex, ResizePanelFlex } from 'react-resize-demo';
// 启用面板变化通知(性能优化)
<ResizePanelGroupFlex
onPanelsChange={(changedIndices) => {
// 只重新渲染变化的面板
}}
>
{/* ... */}
</ResizePanelGroupFlex>详细迁移指南请查看 策略对比文档
📝 版本历史
查看 CHANGELOG.md 了解详细的版本变更历史。
⚡ 性能优化
项目经过多轮性能优化,从初始版本的 30-40 FPS 提升到当前的 50-55 FPS:
- RAF 优化:与浏览器渲染同步,每帧计算一次,减少 DOM 操作 50-70%,降低 CPU 占用 30-50%
- 基于位置的计算:一次性计算所有面板位置,解决快速拖拽时的位置偏移问题
- 虚拟化拖拽:拖拽过程中不操作真实 DOM,减少重排和重绘
- 面板变化通知:只重新渲染变化的面板,减少 React 渲染 70%
- 自动冻结:自动冻结未变化面板,减少布局计算 85%
详细优化时间线和性能对比请查看:
📄 License
MIT
🤝 贡献
欢迎提交 Issue 和 Pull Request!
