Skip to content

LayoutBox 布局模型

布局模型的核心是:组件外面永远有一层 SDK 管的盒子,组件自己只管盒子里面怎么画。

四层字段

字段含义谁消费
PageDocument.layout.canvas画布如何放进宿主容器Renderer / Designer
PageInstance.layoutBox实例自己的外层盒子SDK wrapper
PageInstance.layoutItem实例作为父布局子项时的位置规则父容器布局
PageInstance.containerLayout实例作为容器时,它内部怎么排子组件Renderer / reference 容器

layoutBox

ts
interface LayoutBox {
  x: number
  y: number
  width: number
  height: number
  widthMode: 'px' | 'percent' | 'fill' | 'auto'
  heightMode: 'px' | 'percent' | 'fill' | 'auto'
  overflow?: 'hidden' | 'visible' | 'auto'
}

单位语义:

mode意思典型场景
px固定像素画布上自由摆放的卡片
percent相对父盒子的百分比容器内宽 100%
fill撑满父可用空间运行态卡片填满业务容器
auto由内容决定文本、标签、小按钮

containerLayout

容器内部布局有几种模式:

mode用法
free容器内还能自由拖,子实例 layoutBox.x/y 相对父 outlet
flex类 CSS flex,适合横排/竖排/换行
grid类 CSS grid,适合二维卡片网格
split按比例切分区域,适合左右/上下拆分
free-split容器内任意分割树(递归切左右/上下),每格一个组件;可视化切分 / 合并 / resize / 删除 / 移动交换(0.5.0+)

free-split 与其它模式有两点不同:渲染 data-driven(页面文档里有 free-split 就自动按树渲染,宿主零 opt-in;非 free-split 页零变化)、编辑受 gate(设计器要传 :free-split-enabled="true" 才能编辑)。详见 自由分割布局(free-split)

为什么不直接让组件自己写宽高

因为组件源码属于组件库,而页面里的实例属于页面文档。两者必须分层:

  • 组件源码决定内部结构和默认样式。
  • layoutBox 决定这个实例在页面里占多大、放哪儿、如何裁剪。

这样同一个组件能在多个页面、多个容器里复用。

画布和宿主容器

运行态推荐让宿主容器决定真实宽高:

vue
<section class="h-[520px]">
  <HyperCardPageRenderer :payload="payload" canvas-id="card-a" />
</section>

页面文档里画布可以是 fill。设计态可以模拟宿主容器尺寸,运行态则由真实业务容器接管。

当前不做什么

  • 不做完整 CSS Grid 可视化编辑器。
  • 不做业务布局模板市场。
  • 不自动推断组件内部 DOM 的语义。
  • 不把 padding/margin 放进 SDK 盒模型;这类一般是组件 props 或组件 CSS。

进一步阅读