Skip to content
# tui-yoga-layout

Yoga Flexbox 布局计算 UTS 插件,支持在独立线程中执行布局计算,避免阻塞 UI 线程。

介绍 ​

tui-yoga-layout 是 uni-app x 环境下的 Yoga Flexbox 布局计算引擎插件。调用方传入 JSON 格式的布局配置字符串,插件在平台内部线程 / Worker 中执行 Yoga 布局计算,再以 JSON 字符串形式返回每个节点的测量框(x / y / width / height)与文本逐行数据,供 Canvas 或自研渲染引擎排版绘制。

输入输出均以 JSON 字符串为边界,便于跨线程 / 进程传递与后续扩展。

支持 box / text / image 三种节点:普通容器按 Flexbox 规则计算,文本节点支持原生折行测量并输出逐行数据,图片节点支持本地 / base64 / 网络图解码并按比例参与布局。

支持平台 ​

平台引擎计算位置状态
AndroidYoga Android SDK 2.0.1(.aar)后台线程✅ 全能力
iOSYoga iOS SDK 2.0.1(pod)后台✅ box 全能力(text/image 测量待接入)
HarmonyOS@ohos/yogaWorker 线程✅ 全能力
Webyoga-wasm-web(WASM 内联)Worker / 主线程✅ 全能力(仅异步接口)
微信小程序yoga-wasm-web(asm.js)小程序逻辑层✅ 全能力(仅异步接口)

说明:text 折行 / image 解码测量为各平台渐进接入能力。Android、HarmonyOS、Web、小程序端均已支持;iOS 当前第一迭代仅支持 box 容器布局,text / image 叶子会按普通 box 或显式尺寸处理,lines / loaded 输出暂缺。iOS 同步接口出错时降级返回空字符串(不抛异常),请自行判空。

基础用法 ​

在 uvue / uts 页面中通过 @/uni_modules/tui-yoga-layout 导入:

ts
import { calculateLayoutAsync, calculateLayoutSync, calculateLayout } from '@/uni_modules/tui-yoga-layout'

// 方式一:异步接口(全平台推荐)
const configJson = JSON.stringify({
  width: 320,
  flexDirection: 'row',
  alignItems: 'center',
  children: [
    { id: 'a', width: 100, height: 100 },
    { id: 'b', flex: 1, height: 50 }
  ]
})

const resultJson: string = await calculateLayoutAsync(configJson)
const result = JSON.parse(resultJson)
console.log(result.root.width, result.children.length)

// 方式二:同步接口(小程序 / Web 端不可用,将抛 9010003)
const resultJsonSync: string = calculateLayoutSync(configJson)

// 方式三:options 回调风格(结构化返回)
calculateLayout({
  configJson: configJson,
  success: (res) => {
    console.log(res.root.x, res.root.width)
  },
  fail: (err) => {
    console.error(err.errCode, err.errMsg)
  }
})

页面中使用 ​

vue
<template>
	<view>
		<t-button type="primary" @click="run">计算布局</t-button>
		<text>{{ outJson }}</text>
	</view>
</template>

<script setup>
import { ref } from 'vue'
import { calculateLayoutAsync } from '@/uni_modules/tui-yoga-layout'

const outJson = ref('')

async function run() {
	const configJson = JSON.stringify({
		width: 280,
		flexDirection: 'column',
		children: [
			{ id: 't1', type: 'text', value: '中英文混排自动折行,行高逐行累加', fontSize: 15, lineHeight: 22 },
			{ id: 't2', type: 'text', value: '加粗标题行', fontSize: 16, fontWeight: 'bold', margin: { top: 8 } },
			{ id: 'img1', type: 'image', src: '/static/image/1.png', maxWidth: 200 }
		]
	})
	try {
		const resultJson = await calculateLayoutAsync(configJson)
		const out = JSON.parse(resultJson)
		outJson.value = JSON.stringify(out, null, 2)
	} catch (err) {
		console.error('code=' + err.errCode + ':' + err.errMsg)
	}
}
</script>

更多完整示例见 demo/yoga/yoga.uvue(文本折行、双栏图文、标签换行等运行示例,含 Canvas 排版预览与友好报告)。

API ​

函数列表 ​

函数签名说明
calculateLayoutAsync(configJson: string) => Promise<string>异步计算,返回 JSON 布局结果字符串。全平台推荐,App 端自动丢后台线程,小程序 / Web 端内部走 Worker
calculateLayoutSync(configJson: string) => string同步计算,返回 JSON 布局结果字符串。App / HarmonyOS 可用;小程序 / Web 端抛 9010003
calculateLayout(options: YogaLayoutOptions) => voidoptions 回调风格,成功返回结构化 YogaLayoutResult

calculateLayoutAsync ​

参数 ​

参数说明类型
configJsonYogaLayoutConfig 的 JSON 字符串string

返回值 ​

Promise<string>:YogaLayoutResult 的 JSON 字符串。

Android 端异步阶段会自动并行下载配置中所有 http(s) 图片并测量真实宽高,使网络图与本地 / base64 图一样按真实比例参与布局。

错误 ​

reject 一个 YogaLayoutFail 错误对象(errCode / errMsg,错误码见下表)。

calculateLayoutSync ​

同步计算接口。仅 App(Android / iOS)与 HarmonyOS 可用;小程序 / Web 端因 WASM 需异步初始化将抛出 9010003,请使用异步接口。

参数说明类型
configJsonYogaLayoutConfig 的 JSON 字符串string

注意:

  • Android 端含网络图时内部会同步下载(阻塞等待),请勿在 UI 主线程调用;
  • HarmonyOS 无同步图片解码能力,命中进程内缓存才返回真实尺寸,否则图片按占位返回 loaded=false;
  • iOS 端同步出错时降级返回空字符串(不抛异常),请自行判空。

calculateLayout(options) ​

options 回调风格,内部走异步计算,返回结构化结果。

参数说明类型
configJsonYogaLayoutConfig 的 JSON 字符串string
success计算成功回调,返回 YogaLayoutResult(result) => void
fail计算失败回调,返回错误对象(err: YogaLayoutFail) => void
complete完成回调(成功时触发)(result) => void

数据结构 ​

YogaLayoutConfig(计算入参) ​

字段说明类型
width / height根容器宽高,可选,缺省为 auto(由子内容按 flex 规则撑开,结果 root.width/height 为实际尺寸)number
direction文本方向:inherit / ltr / rtlstring
flexDirection主轴方向:row / column / row-reverse / column-reversestring
flexWrap换行:no-wrap / wrap / wrap-reversestring
justifyContentflex-start / flex-end / center / space-between / space-around / space-evenlystring
alignItems / alignContentflex-start / flex-end / center / baseline / stretchstring
padding根容器内边距YogaEdgeInsets
children子节点数组(可继续嵌套)YogaLayoutNode[]

YogaLayoutNode(节点描述) ​

字段说明类型
type节点类型:box(缺省,可嵌套 children)/ text / imagestring
id节点标识,用于在结果中定位对应布局框string
width / height宽高;number 绝对长度,"NN%" 相对父容器number | string
minWidth / minHeight / maxWidth / maxHeight尺寸约束number | string
flexGrow / flexShrink伸缩比例number
flexBasis'auto' / 数值 / 'NN%'string | number
flex快捷属性,等价于 flexGrow=flex, flexShrink=1, flexBasis=0number
flexDirection / flexWrap / justifyContent / alignItems / alignContent / alignSelfflex 布局属性string
positionrelative / absolutestring
displayflex / nonestring
directioninherit / ltr / rtlstring
overflow溢出裁剪:visible / hidden / scrollstring
top / bottom / left / rightabsolute 定位偏移(支持 number 或 "NN%")number | string
gap主轴子节点间距(仅主轴生效)number
margin / padding / borderWidth外边距 / 内边距 / 边框,支持 number 或 YogaEdgeInsets;borderWidth 不支持百分比YogaEdgeInsets | number
aspectRatio宽高比(宽/高),width / height 至少一个为空时生效number
valuetype='text' 时的文本内容string
fontSize字号(逻辑像素),缺省 16number
fontWeight字重 'normal'(400) / 'bold'(700) 或数字 100~1000,缺省 normalstring | number
fontFamily字体族:'sans-serif'(缺省)/ 'serif' / 'monospace' 或系统字体名string
textAlign文本水平对齐:left / center / right,缺省 leftstring
lineHeight行高,缺省按字体度量自动计算number
srctype='image' 时图片来源:本地绝对路径 / file:// / data:image/...;base64,xxxx / http(s)string
children子节点(box 容器)YogaLayoutNode[]

注意:

  • 尺寸 / 边距百分比("NN%")相对父节点对应维度(绝对定位相对父 padding 框);文本 / 图片叶子不支持百分比 width;
  • gap 仅作用于主轴子节点间距,flexWrap 换行产生的交叉轴“行间距”请用子节点 margin 处理;
  • 文本叶子建议不传 width / height,由原生按可用宽度折行后自动撑开高度;图片叶子建议给 maxWidth(等比缩小上限)或精确 width,否则按解码原图宽高比与可用宽度自适应;解码失败按占位返回 loaded=false。

YogaLayoutResult(计算结果) ​

字段说明类型
root根容器布局框YogaLayoutBox
children全部子节点布局框(扁平数组,树前序遍历顺序),通过 id 与输入节点对应YogaLayoutBox[]

YogaLayoutBox(节点布局框) ​

字段说明类型
id对应输入节点 idstring
type节点类型string
x / y / width / height布局框(相对父节点坐标)number
linestype='text' 时折行后逐行数据YogaLayoutTextLine[]
fontSize / lineHeighttype='text' 时实际采用的字号 / 行高number
loadedtype='image' 时是否成功解码,false 表示按占位尺寸返回boolean
srctype='image' 时原始图片地址(成功 / 占位都会原样返回)string
ratiotype='image' 时实际采用的宽高比(宽/高)number

YogaLayoutTextLine(文本行数据) ​

字段说明类型
text该行渲染的文本string
x该行相对 box 左边界的 xnumber
y该行文字 top 相对 box 上边界的 y(按 lineHeight 累加)number
width该行实际文本测量宽度number
ascent字体基线偏移(负值),canvas 绘制 fillText(text, box.x + x, box.y + y - ascent)number

YogaEdgeInsets ​

字段说明类型
top / bottom / left / right各边值number | string
horizontal / vertical快捷写法,优先级低于 top / bottom / left / rightnumber | string

错误码 ​

遵循 uni 错误码规范(90 开头),错误对象 errSubject 为 tui-yoga-layout。

errCode含义
9010001配置 JSON 解析失败
9010002Yoga 布局计算失败
9010003当前平台不支持该接口(小程序 / Web 端请使用异步接口 calculateLayoutAsync)
9010004该平台实现尚未接入