# @aptre/flex-layout 中文文档

规范地址：https://npmcn.com/package/%40aptre/flex-layout/

版本：0\.6\.4
npm 元数据更新时间：2026-04-21T04:37:40.590Z
中文译文更新时间：2026-11-06T13:06:30.039Z
软件包许可：ISC

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40aptre/flex-layout
原文对照：https://npmcn.com/package/%40aptre/flex-layout/?lang=original
项目主页：https://flexlayout.spacewave.app/
源码仓库：https://github.com/aperturerobotics/flex-layout

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：2 MB，144 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：0 个
- peer 依赖：react ^19\.2\.5，react-dom ^19\.2\.5
- 首次发布：2023-10-18T21:59:18.563Z
- 最新版本发布：2026-04-21T04:37:40.318Z
- 近 30 天下载量：21931（2026-10-07 至 2026-11-05，npm 官方下载统计）
- 已发布版本数：49（近 12 个月 22 个）

## 中文简介

多塔布局管理器

## 安装

```sh
npm install @aptre/flex-layout
```

也可以使用：`pnpm add @aptre/flex-layout`、`yarn add @aptre/flex-layout`、`bun add @aptre/flex-layout`

## README

# FlexLayout (英语)

[![npm](https://img.shields.io/npm/v/@aptre/flex-layout?style=flat-square)](https://www.npmjs.com/package/@aptre/flex-layout) [![Build status](https://img.shields.io/github/actions/workflow/status/aperturerobotics/flex-layout/tests.yml?style=flat-square&branch=master)](https://github.com/aperturerobotics/flex-layout/actions) [![GitHub](https://img.shields.io/github/license/Caplin/FlexLayout)](https://github.com/caplin/FlexLayout/blob/master/LICENSE) [![Website](https://img.shields.io/badge/demo-flexlayout.spacewave.app-blue?style=flat-square)](https://flexlayout.spacewave.app/)

FlexLayout是支持多个 TabSets 的布局管理器,带有可拖动+重力标签.

![FlexLayout Demo Screenshot](https://npmcn.com/package/%40aptre/flex-layout/Screenshot_light.png?raw=true "FlexLayout Demo Screenshot")

**这是一个特色叉 [FlexLayout (英语)](https://github.com/caplin/FlexLayout) 由卡普林执导.** 最初的项目在一段时间内没有更新过,因此这个分叉包括了bug修正,性能改进等新功能 `OptimizedLayout`。 。 。 .

```bash
npm install @aptre/flex-layout
yarn add @aptre/flex-layout
pnpm add @aptre/flex-layout
bun add @aptre/flex-layout
```

FlexLayout唯一的依赖是反应.

特征 :

-   分隔符
-   选项卡
-   选项卡拖放和顺序
-   选项卡集拖放( 在一个操作中移动标签集中的所有标签)
-   连接到标签集或边框
-   最大化标签集(双击标签集头或使用图标)
-   选项卡溢出( 标签溢出时显示菜单, 使用鼠标转盘滚动标签)
-   边框标签集
-   选项卡重命名( 双击标签文本重命名)
-   主题 - 轻、下划线、灰色、圆和暗
-   移动设备(iPad、Android)
-   使用拖动添加标签, 添加到活动标签集, 添加到由 id 设置的标签
-   选项卡和标签集属性:启用TabStrip,启用Dock,启用Drop...
-   可自定义标签和标签集渲染
-   移动标签时保留组件状态
-   类型声明
-   **优化 版式** - 将标签内容置于FlexLayout的DOM之外,以提高性能

## 演示

尝试交互式演示 [fleexlayout. 空间波.app](https://flexlayout.spacewave.app/)。 。 。 .

API 文档可见于 [fleexlayout.spacewave.app/typedoc/ 互联网档案馆的存檔,存档日期2013-12-02](https://flexlayout.spacewave.app/typedoc/)。 。 。 .

要在本地运行测试,克隆这个repo,然后:

```
bun install
bun run test:browser
```

## 安装

FlexLayout在 npm 仓库中. 使用 :

```
npm install @aptre/flex-layout
```

在模块中导入 FlexLayout :

```
import {Layout, Model} from '@aptre/flex-layout';
```

包含光线、下划线、灰色或暗色主题:

添加额外导入 :

```
import '@aptre/flex-layout/style/light.css';
```

或将 cs 添加到您的 html 中:

```
<link rel="stylesheet" href="node_modules/@aptre/flex-layout/style/light.css" />
```

## 使用量

这个 `<Layout>` 组件使制表器和分页器具有下列道具:

#### 所需的道具 :

| Prop | 说明 |
| --- | :-- |
| 模式 | 布局模式 |
| 工厂 | 用于创建 React 组件的工厂函数 |

额外 [可选道具](https://npmcn.com/package/%40aptre/flex-layout/#readme-optional-layout-props)

模型是定义布局结构的节点对象树.

工厂是一个函数,它取出一个节点对象并返回一个反应组件,该组件应该由布局中的标签来托管.

模型可以使用Model. from Json(json Object)静态方法创建,也可以使用model.toJson()方法保存.

## 示例配置 :

```javascript
var json = {
    global: {},
    borders: [],
    layout: {
        type: "row",
        weight: 100,
        children: [
            {
                type: "tabset",
                weight: 50,
                children: [
                    {
                        type: "tab",
                        name: "One",
                        component: "button",
                    },
                ],
            },
            {
                type: "tabset",
                weight: 50,
                children: [
                    {
                        type: "tab",
                        name: "Two",
                        component: "button",
                    },
                ],
            },
        ],
    },
};
```

## 示例代码

```javascript
const model = Model.fromJson(json);

function App() {
    const factory = (node) => {
        var component = node.getComponent();

        if (component === "button") {
            return <button>{node.getName()}</button>;
        }
    };

    return <Layout model={model} factory={factory} />;
}
```

上述代码将使两个制表符横向各包含一个主机按钮组件的单个制表符. 标签可以通过拖放来移动并调整大小. 通过向模型发送动作,可以在布局上添加额外的网格.

## 优化 版式

`OptimizedLayout` 是一个包裹周围 `Layout` 将标签内容置于 FlexLayout 的 DOM 结构之外,以便更好的性能。 这对复杂的标签内容特别有用,当布局模型改变时,这些标签内容不应该重新回复.

### 主要惠益

1.  **对布局变化没有重新回复** - 当模型改变时,标签组件不重新提交
2.  **国家保全** - Tab 状态(滚动位置、窗体输入等)在整个布局变异中保留
3.  **CSS 仅更新** - 只有CSS属性在布局变化时会改变,避免重现

### 如何运作

1.  `OptimizedLayout` 调制 `Layout` 轻量级 `TabRef` 占位符而不是实际标签内容
2.  `TabRef` 组件从 `TabNode`编号
3.  一个兄弟 `TabContainer` 使实际标签内容具有绝对位置
4.  在拖动操作中, `TabContainer` 用途 `pointer-events: none` 防止干扰 FlexLayout 拖放

### 示例使用

```tsx
import { Model, OptimizedLayout } from "@aptre/flex-layout";
import "@aptre/flex-layout/style/light.css";

const json = {
    global: {},
    borders: [],
    layout: {
        type: "row",
        weight: 100,
        children: [
            {
                type: "tabset",
                weight: 50,
                children: [{ type: "tab", name: "Editor", component: "editor" }],
            },
            {
                type: "tabset",
                weight: 50,
                children: [{ type: "tab", name: "Preview", component: "preview" }],
            },
        ],
    },
};

const model = Model.fromJson(json);

function App() {
    // renderTab receives a TabNode and returns the content for that tab
    const renderTab = (node) => {
        const component = node.getComponent();

        if (component === "editor") {
            return <Editor />;
        }
        if (component === "preview") {
            return <Preview />;
        }
        return <div>Unknown component: {component}</div>;
    };

    return (
        <div style={{ position: "relative", width: "100%", height: "100vh" }}>
            <OptimizedLayout model={model} renderTab={renderTab} />
        </div>
    );
}
```

### 道具

`OptimizedLayout` 接受所有与 `Layout`,但:

-   **`renderTab`** (需要) - 替换 `factory`函数 `TabNode` 并返回反应元素,以制成标签内容.

所有其他 `Layout` 道具( r)`model`, (中文(简体) ), `onModelChange`, (中文(简体) ), `classNameMapper`) 工作方式相同.

### 何时使用优化Layout

使用 `OptimizedLayout` 当:

-   您的标签内容很昂贵
-   您需要在整个布局变化中保留内部组件状态
-   您有很多标签, 想要最小化重接

使用标准 `Layout` 当:

-   当模型改变时, 您需要重新提交标签内容
-   您的标签内容简单而轻巧
-   你需要工厂模式来装入懒惰的部件

## JSON模型结构

模型json包含3个顶级元素:

-   全球 - (可选) 定义全球选项
-   布局 - 主行/tabset/tabs布局等级
-   边框 - (可选) 最多定义了 4 个边框 ("上","下","左","右")

使用3个“ 节点” 类型来构建布局元素 :

-   行 - 行包含一个标签集和子行列表,顶级的"行"将水平渲染(除非设置了全局属性根OrientationVertical) ,孩子的"rows"将会在相反的方向向父母行.
    
-   选项卡集 - 选项卡集包含一个标签列表和所选标签索引
    
-   选项卡 - 选项卡指定它们应该主机的组件名称(这些组件将通过工厂加载)和实际选项卡的文本.
    

版式结构由行内包含自有标签的标签集来定义.

可选边界元素由边界节点组成

-   边框 - 边框包含标签列表和所选标签的索引,它们只能用于边框 顶级元素.

JSON 模型的树结构被很好的定义为 Typescription 接口,参见 [JSON 模型](https://npmcn.com/package/%40aptre/flex-layout/#readme-json-model-definition)

每类节点都有一组定义的要求/可选属性.

行和制表盘上的重量指定了这些节点在母行内的相对权重,实际值并不仅仅关系它们的相对值(一是两个制表盘的重量为30,70,如果它们有3,7的权重,它们就会产生同样的效果.

通过改变全局或节点属性,可以改变布局外观和功能,例如:

在全局选项中设置标签SetEnableTabStrip:false会将布局改变为多分配器( 没有) 选项卡或拖放.

```
 global: {tabSetEnableTabStrip:false},
```

## 示范行动

模型json被装入后,模型中的所有修改都会通过动作应用.

您使用 `Model.doAction()` 方法.

此方法使用单个参数, 由一个动作创建 发电机(通常以 `FlexLayout.Actions.<actionName>`) (中文(简体) ).

见 [动作.ts](https://npmcn.com/package/%40aptre/flex-layout/src/model/Actions.ts) 用于可用的行动.

### 实例

```js
model.doAction(
    FlexLayout.Actions.updateModelAttributes({
        splitterSize: 40,
    }),
);
```

上面的例子会增加拆分器的大小,可以用来制作 调整小设备上的布局更方便.

```js
model.doAction(FlexLayout.Actions.addNode({ type: "tab", component: "grid", name: "a grid", id: "5" }, "1", FlexLayout.DockLocation.CENTER, 0));
```

此示例在标签集中心以 id "1" 为单位添加了新的网格组件,并在 0't tab 位置上添加了新的网格组件(使用值 - 1来添加到标签的结尾).

注:您可以得到节点的ID(例如,节点由节点返回) `addNode` 动作)使用方法 `node.getId()`。 。 。 . 如果在节点创建时没有指定一个代号,那么一个代号将会以形式为您创建 `#<uuid>` (例如:. `#0c459064-8dee-444e-8636-eb9ab910fb27`) (中文(简体) ).

注意: 您可以在应用 GUI 更改前先截取操作 执行 `onAction` 调用属性 `Layout`。 。 。 .

## 可选版式道具

在布局上可以应用许多可选属性. 见 [在布局.tsx 中的 ILayoutProps](https://npmcn.com/package/%40aptre/flex-layout/src/view/Layout.tsx) 用于完整的接口.

## JSON 示范定义

JSON模型被很好地定义为一组TypeScript接口. 见 [IJsonModel.ts (英语)](https://npmcn.com/package/%40aptre/flex-layout/src/model/IJsonModel.ts) 用于所有可用属性:

-   `IJsonModel` - 顶级模型结构
-   `IGlobalAttributes` - 全球配置属性
-   `IJsonRowNode` - 行配置属性
-   `IJsonTabSetNode` - 标签集配置属性(注意:标签集在移动标签时是动态创建的,在空出时被删除,除非 `enableDeleteWhenEmpty` 错误)
-   `IJsonTabNode` - 标签配置属性
-   `IJsonBorderNode` - 边界配置属性

## 创建新标签的布局组件方法

布局组件中有添加标签的方法 。 见 [版式.tsx](https://npmcn.com/package/%40aptre/flex-layout/src/view/Layout.tsx) 用于现有方法.

示例

```
layoutRef.current.addTabToTabSet("NAVIGATION", {type:"tab", component:"grid", name:"a grid"});
```

这将在带有 id “ NAVIGATION” 的标签集中添加一个新的网格组件( 其中版式参考文件是对版式元素的回溯, 参见 [https://react.dev/learn/reference-values- with-refs 互联网档案馆的存檔,存档日期2013-12-02](https://react.dev/learn/referencing-values-with-refs) ) (中文(简体) ).

## 标签节点事件

您可以在节点上通过添加一个收听器处理事件, 通常这样做 当组件以使用效果方法挂起时:

示例

```
    function MyComponent({node}) {

      useEffect(() => {
        // save subject in flexlayout node tree
        node.setEventListener("save", () => {
             node.getConfig().subject = subject;
           };
        }, []);
    }

```

| 活动 | 参数 | 说明 |
| --- | :-- | --- |
| 调整大小 | \[ rect\] (英语) | 当标签在布局时调整大小时调用, 调用后, 才会用新大小渲染 |
| 关闭 | 无 | 关闭标签时调用 |
| 可见度 | {可看见} | 当标签的能见度改变时调用 |
| 保存 | 无 | 在标签节点被序列化为json之前调用, 用于通过将数据添加到由节点返回的对象中来保存节点配置 。 getConfig () |

## 替代布局管理器

| 名称 | 仓库 |
| --- | :-- |
| 弧-多克 | [https://github.com/ticlo/rc-dock (中文(简体) )](https://github.com/ticlo/rc-dock) |
| 挂起视图 | [https://dockview.dev/ (英语)](https://dockview.dev/) |
| 发光 | [https://github.com/jupyterlab/lumino 页面存档备份,存于互联网档案馆](https://github.com/jupyterlab/lumino) |
| 黄金铺出 | [https://github.com/golden-layout/golden-layout 页面存档备份,存于互联网档案馆](https://github.com/golden-layout/golden-layout) |
| 反应-发作 | [https://github.com/nomcopter/react-mosaic 互联网档案馆的存檔,存档日期2013-12-21](https://github.com/nomcopter/react-mosaic) |

## 常见问题

### @aptre/flex-layout 是什么？

多塔布局管理器

### 如何安装 @aptre/flex-layout？

在项目目录运行 npm install @aptre/flex-layout，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（^19\.2\.5）、react-dom（^19\.2\.5）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @aptre/flex-layout 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @aptre/flex-layout 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @aptre/flex-layout 可以商用吗？

@aptre/flex-layout 使用 ISC 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @aptre/flex-layout 的下载量有多少？

根据 npm 官方下载统计，@aptre/flex-layout 在 2026/10/07 – 2026/11/05 这 30 天内被下载 21,931 次，日均约 731 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @aptre/flex-layout 还在维护吗？

最新版本 0\.6\.4 发布于 2026/04/21（6 个月前）；至今共发布 49 个版本，其中过去 12 个月发布了 22 个；首次发布于 2023/10/19。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

