快速上手
安装、受控组件用法、跨端注意与包 source 字段约定。
安装
bash
bun add transone-ui受控组件用法
组件全部为受控组件:状态由父级维护,交互通过 click / change / input / close 等自定义事件回传,父级用 emitters 订阅:
ts
import { Component, createComponent, h } from 'transone';
import { TuButton, TuInput, TuPopup } from 'transone-ui';
class MyPage extends Component {
protected initState() {
return { text: '', popupVisible: false };
}
protected render() {
return h('div', { className: 'page' }, [
createComponent({
component: TuInput,
props: { value: this.state.text, clearable: true },
emitters: { input: (v: string) => (this.state.text = v) },
}),
createComponent({
component: TuButton,
props: { type: 'primary' },
children: ['打开弹层'],
emitters: { click: () => (this.state.popupVisible = true) },
}),
createComponent({
component: TuPopup,
props: { visible: this.state.popupVisible, position: 'bottom' },
children: [h('div', {}, ['弹层内容'])],
emitters: { close: () => (this.state.popupVisible = false) },
}),
]);
}
}全部组件与属性 / 事件见组件列表下的 17 个组件页。
跨端注意
- 插槽内的动态文本:小程序端插槽内容编译在父级 wxml、绑定父级数据;Web 端插槽内容绑定的是组件自身 state(为空时
{{}}渲染为空)。不要在组件 children 插槽里写模板插值,改用模板表达式字符串,例如`计数:${this.state.count}`,或将动态文本放在页面直属节点。 - each() 返回数组:作为 children 直接传入([object Object]),不要再包一层数组字面量(Web 渲染器只铺一层 children)。
- 子节点类型:children 只接受
VNode | string;数字先转字符串(模板表达式自动转换)。 - 标签映射:div → view、span → text;小程序端 text 内不能放 view / slot,所以 TuTag 根节点使用 div。
- 事件回传:组件用
emit(name, ...args)回传,父级用createComponent({ ..., emitters })订阅;小程序端编译为页面包装方法并绑定bind:name,同名事件自动加序号避免覆盖。 - 组件内部:渲染(非插槽部分)不要使用 {{}},一律通过 props 传入数据。
小程序端样式与交互适配
- 间距不使用 flex
gap(老内核 WebView 支持不稳定),组件内一律用子元素margin实现。 - 样式避免高级选择器(如
:not());条件样式用类名(--checked/--visible)或directions.show切换。 - 安全区使用双声明:先写固定值兜底,再写
calc(env(safe-area-inset-bottom) + Npx)覆盖。 - 列表取数:渲染
dataIndex属性(mp 编译为data-index=""),回调从e.currentTarget.dataset.index读取,双端一致。 TuSearchBar提供confirmType(小程序键盘确认键文案),Web 端忽略;回车触发search事件。- 行内 style 的
var()若在端上不解析,同属性在 wxss 类中有默认值兜底;主题定制优先在app.wxss覆盖令牌。 - 弹层(Toast / Modal / ActionSheet / Popup)用
position: fixed渲染于组件内部,层级统一为--tu-popup-z-index(默认 1000)。
包 source 字段约定(CLI 编译依赖)
transone-cli 编译小程序时,从 node_modules/<包>/package.json 读取 "source" 字段定位该包的 TypeScript 入口,再沿 export / re-export 链解析组件类的实际文件。因此发布组件库时必须声明:
json
{
"name": "transone-ui",
"source": "./lib/index.ts",
"peerDependencies": { "transone": ">=0.1.2" }
}注意
只有 source 指向的入口及其 re-export 链中的类会被静态编译分析;组件的 render() / initState() / initStyles() 需保持静态可分析(字面量、三元、&&、each 等受支持语法),方法体独立翻译、不能闭包捕获。开发
bash
# 构建 dist(类型声明 + Bun.build)
bun run --cwd packages/transone-ui build
# 组件运行时测试(Web DOM 环境)
bun test packages/transone-ui/tests/components.test.ts
# 演示页整页集成测试(覆盖受控数据流)
bun test packages/transone-ui/tests/demo-integration.test.ts演示项目位于 playground/ui-demo,覆盖全部组件与受控交互,可分别构建 Web / 微信 / 阿里 / 字节产物。