Skip to content

写一个布局组件

让其他开发者写出像 flex/grid/split/free 那样的布局容器,接入 SDK 协议(outlet + containerLayout + layoutItem)。


1. 布局协议三层

PageDocument
  └─ PageInstance (实例)
       ├─ layoutBox     (自身盒子:x/y/width/height + mode 'px'/'percent'/'fill'/'auto')
       ├─ layoutItem    (作为父布局子项时:flex order/grid row/split ratio)
       └─ containerLayout (作为容器时:内部排子用啥 mode 'free'/'flex'/'grid'/'split')
  • 组件源码只提供 outlet(<div data-hc-slot="default">),不写 display/grid/flex
  • SDK 按 containerLayout 自动施加 CSS 到 outlet
  • 子按 layoutItem 自动定位

2. 最小可用布局组件(flex 范例)

HTML:

html
<div class="my-flex">
  <div class="my-flex__body" data-hc-slot="default"></div>
</div>

JS:

js
export default {
  name: { value: 'MyFlexContainer', CN: 'My Flex 容器' },
  slots: [{ name: 'default', multiple: true, label: 'flex 内容区' }],
  custom: {},
  method: {},
  data() { return {} },
  methods: {},
}

CSS:

css
.my-flex {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
}
.my-flex__body {
  box-sizing: border-box;
  min-height: 120px;
  /* ★ 不写 display:flex,SDK 接管 */
}

用户切 containerLayout.mode = 'flex' 后,SDK 给 __bodydisplay:flex; flexDirection: row; gap: 8px; ...(按 ContainerLayoutConfig 字段)。


3. 四种容器模式速览

mode用途SDK 施加 CSS子定位字段
free自由摆放(画板)position: relativelayoutBox.x/y 绝对定位
flex流式排布(表单 / 横竖排)display: flex; flexDirection; gap; ...layoutItem.order/grow/shrink
grid二维网格(仪表盘)display: grid; gridTemplateColumns/RowslayoutItem.row/column 1-based + rowSpan/columnSpan
split比例分屏(主从)display: grid; fr trackslayoutItem.ratio(主轴)+ 交叉轴 fill

4. 关键约束(★ 必读)

A. 只 default slot 施加 containerLayout(M1)

containerLayout 协议只描述 default slot。多 slot 容器(如 dock layout 有 top/left/right/bottom/main):

  • main(default)享受 SDK 自动布局
  • top/left/right/bottom 由组件源码 CSS 写死

B. SDK 施加 outlet 样式"先全清再写"(L1)

切 mode 时(grid → flex)SDK 自动清干净旧 mode 的 CSS。组件源码不要写 display / grid* / flex* / gap 等 SDK-owned key。

C. free outlet 必须 position: relative

嵌套 free 子的根因。SDK 给 free outlet 加 position: relative 当定位上下文(子 position: absolute)。

D. 子定位单一真相 = child.layoutItem(D2)

田字格 / 分隔条拖动 / 属性面板编辑都写 child.layoutItem,写父 cells / ratios。父 cells / ratios 降级为 legacy fallback。

E. 进入布局托管容器子默认 fill(C2)

flex / grid / split 容器进入时,子 widthMode='fill', heightMode='fill',fill 轴不渲 resize 把手(C3)。

free 容器强制 fill,子保留组件固有尺寸。


5. 加新的 main slot mode(如 'dock')

需要改 SDK 协议(改动大):

  1. SDK ContainerLayoutMode enum 加 'dock'
  2. containerLayoutToCss 加 dock 分支
  3. layoutItemToCss 处理 dock layoutItem
  4. normalize / validate 加 dock 校验
  5. InteractionLayer.resizeHandles + useCanvasInteraction.handleResizeStart 加 dock 把手门控
  6. backend validateLayout 白名单加 'dock'
  7. ContainerLayoutPanel 加 dock mode 切换按钮

强烈建议先走"路 A"(组件源码自布局多 slot + main slot 用现有 4 mode),避免 SDK 协议改动大。