react-resize-demo
v3.0.0
Published
A React component library demo
Readme
react-resize-demo
一个现代化的 React 可调整大小面板组件库,支持水平和垂直方向的布局调整,具备完整的 TypeScript 支持和模块化架构。
源码地址: https://gitee.com/zugechen/react-resize-demo
✨ 特性
- ✅ 多种策略:提供 4 种 resize 策略(Basic、Linked、Flex、Flex-Linked),适应不同场景
- ✅ 双向布局:支持水平和垂直方向的布局
- ✅ 拖拽调整:可拖拽调整相邻面板的宽度/高度
- ✅ 最小尺寸:支持设置面板最小尺寸限制
- ✅ 级联调整:当面板达到最小值时,自动从相邻面板获取空间
- ✅ 虚拟化拖拽:支持虚拟节点模式,拖拽时创建虚拟框架,提升性能
- ✅ 性能优化:节流优化、面板变化通知、自动冻结等多项性能优化
- ✅ TypeScript:完整的 TypeScript 类型支持
- ✅ 模块化架构:按策略分类的清晰目录结构,支持按需导入
- ✅ Tree-shaking:支持 Tree-shaking,减少打包体积
- ✅ 代码压缩:自动压缩代码,优化打包体积
📦 安装
npm install react-resize-demo
# 或
yarn add react-resize-demo
# 或
pnpm add react-resize-demo🚀 快速开始
基础用法(推荐使用 Flex-Linked 策略)
import { ResizePanelGroupFlexLinked, ResizePanelFlexLinked } from 'react-resize-demo';
function App() {
return (
<div style={{ width: '100%', height: '500px' }}>
<ResizePanelGroupFlexLinked direction="horizontal">
<ResizePanelFlexLinked minSize={100}>
<div>Panel 1</div>
</ResizePanelFlexLinked>
<ResizePanelFlexLinked minSize={200}>
<div>Panel 2</div>
</ResizePanelFlexLinked>
<ResizePanelFlexLinked minSize={300}>
<div>Panel 3</div>
</ResizePanelFlexLinked>
</ResizePanelGroupFlexLinked>
</div>
);
}其他策略
项目提供 4 种策略,可根据场景选择:
- Basic 策略:适合面板数量 < 10 的简单场景
- Linked 策略:适合面板数量 ≥ 10 的场景
- Flex 策略:适合需要精确控制占比的场景
- Flex-Linked 策略:适合大量面板 + 精确控制的场景(推荐)
详细对比请查看 策略对比文档
垂直布局
<ResizePanelGroupFlexLinked direction="vertical" style={{ height: '500px' }}>
<ResizePanelFlexLinked minSize={100}>
<div>顶部面板</div>
</ResizePanelFlexLinked>
<ResizePanelFlexLinked minSize={200}>
<div>中间面板</div>
</ResizePanelFlexLinked>
<ResizePanelFlexLinked minSize={100}>
<div>底部面板</div>
</ResizePanelFlexLinked>
</ResizePanelGroupFlexLinked>虚拟化模式
虚拟化模式可以在拖拽时创建虚拟节点框架,拖拽过程中只更新虚拟节点,拖拽结束后再应用到真实节点。这可以提升性能,特别是在处理复杂内容的面板时。
// 启用虚拟化(使用默认样式)
<ResizePanelGroupFlexLinked virtual={true}>
<ResizePanelFlexLinked minSize={100}>
<div>Panel 1</div>
</ResizePanelFlexLinked>
<ResizePanelFlexLinked minSize={200}>
<div>Panel 2</div>
</ResizePanelFlexLinked>
</ResizePanelGroupFlexLinked>
// 启用虚拟化 + 面板变化通知(推荐)
<ResizePanelGroupFlexLinked
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));
// 只重新渲染变化的面板,提升性能
}}
>
<ResizePanelFlexLinked minSize={100}>
<div>Panel 1</div>
</ResizePanelFlexLinked>
<ResizePanelFlexLinked minSize={200}>
<div>Panel 2</div>
</ResizePanelFlexLinked>
</ResizePanelGroupFlexLinked>按需导入
支持分层导入,实现更好的 Tree-shaking:
// 从主入口导入(推荐)
import { ResizePanelGroupFlexLinked, ResizePanelFlexLinked } from 'react-resize-demo';
// 按需导入组件
import { ResizePanelGroupFlexLinked } from 'react-resize-demo/components';
import { ResizePanelFlexLinked } from 'react-resize-demo/components';
// 策略特定导入(高级用法)
import { ResizePanelGroupFlexLinked } from 'react-resize-demo/strategies/flex-linked/components/ResizePanelGroupFlexLinked';
// 导入核心工具
import { PanelManager } from 'react-resize-demo/core/PanelManager';
// 导入类型
import type { VirtualConfig, ResizeDirection } 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 文档
ResizablePanelGroup
面板组容器组件,用于包裹多个 ResizablePanel。
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| direction | 'horizontal' \| 'vertical' | 'horizontal' | 布局方向 |
| virtual | boolean | false | 是否启用虚拟化模式 |
| virtualConfig | VirtualConfig | {} | 虚拟化配置(仅在 virtual=true 时生效) |
| style | React.CSSProperties | - | 自定义样式 |
| children | React.ReactNode | - | 子元素(通常是多个 ResizablePanel) |
VirtualConfig
虚拟化配置对象:
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| enabled | boolean | false | 是否启用虚拟化(通常通过 virtual prop 设置) |
| style | React.CSSProperties | - | 虚拟节点的自定义样式 |
| className | string | - | 虚拟节点的自定义类名 |
ResizablePanel
可调整大小的面板组件。
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| minSize | number | 100 | 面板最小尺寸(像素) |
| onResize | (width: number) => void | - | 面板尺寸变化时的回调函数 |
| children | React.ReactNode | - | 面板内容 |
Context & Hooks
import { ResizableContext, useResizableContext } from 'react-resize-demo';
// 在组件内部使用
const {
panelCount,
registerPanel,
unregisterPanel,
getPanelInfo,
direction,
virtualConfig
} = useResizableContext();🏗️ 项目结构
react-resize-demo/
├── src/ # 源代码目录
│ ├── strategies/ # 策略目录(按策略分类)
│ │ ├── basic/ # Basic 策略
│ │ │ ├── components/
│ │ │ ├── context.tsx
│ │ │ └── resizeAble.ts
│ │ ├── linked/ # Linked 策略
│ │ ├── flex/ # Flex 策略
│ │ └── flex-linked/ # Flex-Linked 策略(推荐)
│ ├── core/ # 核心工具(所有策略共享)
│ │ ├── PanelManager.ts
│ │ ├── virtualNode.ts
│ │ └── throttle.ts
│ ├── components/ # 组件统一导出
│ │ └── index.tsx
│ ├── types/ # 类型定义
│ │ └── index.ts
│ └── index.ts # 主入口文件
├── demo/ # 本地测试Demo
│ ├── StrategyComparison.tsx # 策略对比演示
│ └── ...
├── docs/ # 文档目录
│ ├── STRATEGY_COMPARISON.md # 策略对比文档
│ ├── PERFORMANCE_TIMELINE.md # 性能优化时间线
│ ├── THROTTLE_OPTIMIZATION.md # 节流优化文档
│ └── PANEL_CHANGE_NOTIFICATION.md # 面板变化通知文档
├── dist/ # 构建输出目录
│ ├── index.js # CJS 主入口
│ ├── esm/ # ESM 模块
│ ├── strategies/ # 策略目录
│ ├── core/ # 核心工具
│ └── types/ # 类型定义
├── rollup.config.mjs # Rollup构建配置
└── package.json # 项目配置详细的项目结构说明请查看 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💡 工作原理
组件通过拖拽器(ResizeHandle)来调整相邻面板的尺寸:
- 向右拖拽:扩大左侧面板,缩小右侧面板(如果右侧面板达到最小值,继续从后续面板获取空间)
- 向左拖拽:缩小左侧面板,扩大右侧面板(如果左侧面板达到最小值,继续从前面面板获取空间)
拖拽器会自动插入到相邻面板之间,无需手动添加。
虚拟化模式
当启用虚拟化模式(virtual={true})时:
- 拖拽开始:为所有相关面板创建虚拟节点框架,虚拟节点覆盖在原节点上
- 拖拽中:只更新虚拟节点的尺寸和位置,真实节点保持不变
- 拖拽结束:将虚拟节点的最终尺寸应用到真实节点,然后清理所有虚拟节点
这种模式可以:
- 提升性能:拖拽过程中不操作真实 DOM,减少重排和重绘
- 提供视觉反馈:虚拟节点可以有不同的样式(如半透明、虚线边框等)
- 适用于复杂内容:当面板内容复杂时,虚拟化可以避免拖拽时的性能问题
🔄 迁移指南
从 2.x 升级到 3.0
3.0 版本引入了策略分类架构,推荐使用 Flex-Linked 策略:
// 2.x 版本(仍然可用,向后兼容)
import { ResizePanelGroup, ResizePanel } from 'react-resize-demo';
// 3.0 版本(推荐)
import { ResizePanelGroupFlexLinked, ResizePanelFlexLinked } from 'react-resize-demo';新功能
3.0 版本新增了多种策略和性能优化:
// 使用 Flex-Linked 策略(推荐,性能最佳)
import { ResizePanelGroupFlexLinked, ResizePanelFlexLinked } from 'react-resize-demo';
// 启用面板变化通知(性能优化)
<ResizePanelGroupFlexLinked
onPanelsChange={(changedIndices) => {
// 只重新渲染变化的面板
}}
>
{/* ... */}
</ResizePanelGroupFlexLinked>详细迁移指南请查看 策略对比文档
📝 版本历史
查看 CHANGELOG.md 了解详细的版本变更历史。
⚡ 性能优化
项目经过多轮性能优化,从初始版本的 30-40 FPS 提升到当前的 50-55 FPS:
- 节流优化:使用
requestAnimationFrame节流,减少 DOM 操作 50-70% - 虚拟化拖拽:拖拽过程中不操作真实 DOM,减少重排和重绘
- 面板变化通知:只重新渲染变化的面板,减少 React 渲染 70%
- 自动冻结:自动冻结未变化面板,减少布局计算 85%
- 链表优化:大量面板场景下性能提升 42.9%
详细优化时间线和性能对比请查看:
📄 License
MIT
🤝 贡献
欢迎提交 Issue 和 Pull Request!
