视图构建
h()
创建虚拟视图节点,是 JSX 编译的底层实现。
类型定义
ts
declare function h<T extends ViewDescriptor>(
type: T,
propsOrChildren?: AnyProps | RenderChildren,
children?: RenderChildren
): InferView<T>参数
| 参数 | 类型 | 说明 |
|---|---|---|
type | ViewDescriptor | 标签名、组件或 ViewBuilder |
propsOrChildren | AnyProps | RenderChildren | 属性或子节点 |
children | RenderChildren | 子节点 |
返回值
| 类型 | 说明 |
|---|---|
InferView<T> | 视图对象 |
示例
tsx
import { h } from 'vitarx'
// 创建元素
const el = h('div', { class: 'container' }, 'Hello')
// 创建组件
const comp = h(MyComponent, { prop: 'value' })
// 嵌套子节点
const nested = h('div', null, [h('span', null, 'Hello'), h('span', null, 'World')])dynamic()
动态渲染视图,支持运行时响应式切换。
类型定义
ts
declare function dynamic<T>(build: () => T, location?: CodeLocation): DynamicView<T>参数
| 参数 | 类型 | 说明 |
|---|---|---|
build | () => T | 返回视图的渲染函数 |
location | CodeLocation | 可选的代码位置信息 |
返回值
| 类型 | 说明 |
|---|---|
DynamicView<T> | 动态视图对象 |
示例
tsx
import { dynamic, ref } from 'vitarx'
function App() {
const show = ref(true)
return dynamic(() => {
return show.value ? <div>显示</div> : <div>隐藏</div>
})
}参考:dynamic 详解
mergeProps()
合并多个属性对象,处理 class 和 style 的特殊合并逻辑。
类型定义
ts
declare function mergeProps(p1: AnyProps, p2: AnyProps): AnyProps参数
| 参数 | 类型 | 说明 |
|---|---|---|
p1 | AnyProps | 第一个属性对象 |
p2 | AnyProps | 第二个属性对象 |
返回值
| 类型 | 说明 |
|---|---|
AnyProps | 合并后的属性对象 |
示例
ts
import { mergeProps } from 'vitarx'
const merged = mergeProps({ class: 'a', id: 'test' }, { class: 'b', style: 'color: red' })
// { class: 'a b', id: 'test', style: 'color: red' }render()
将视图或组件命令式渲染到指定容器。适合在组件库封装中渲染弹窗、Toast、全局通知等脱离组件树的独立视图。
类型定义
ts
// 重载一:渲染组件
declare function render<T extends Component>(
component: T,
container: HostContainer,
ctx?: ViewContext
): ComponentView<T>
// 重载二:渲染视图
declare function render<T extends View>(view: T, container: HostContainer, ctx?: ViewContext): T参数
| 参数 | 类型 | 说明 |
|---|---|---|
view | View | Component | 要渲染的视图对象或组件函数(函数会自动包装为组件视图) |
container | HostContainer | 视图将被挂载到的宿主容器 |
ctx | ViewContext | 可选的视图上下文 |
ctx 可包含以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
app | App | 可选的应用实例 |
owner | Component | 可选的父组件实例 |
返回值
| 类型 | 说明 |
|---|---|
View | 渲染后的视图实例,类型与输入视图类型一致 |
异常
| 错误信息 | 触发条件 |
|---|---|
render() param $1 must be a function or a View instance | 参数既不是函数也不是视图实例 |
示例
渲染组件到 body 中(封装弹窗类组件库的典型用法):
ts
import { ModalComponent } from 'xxxx'
// 渲染组件到body中
const view = render(ModalComponent, document.body)
setTimeout(() => {
view.dispose() // 销毁
}, 3000)渲染 JSX 视图:
tsx
const view = render(<div>Hello World</div>, document.body)
setTimeout(() => {
view.dispose() // 销毁
}, 3000)builder()
将一个函数标记为视图构建器(ViewBuilder)。构建器在 JSX 中被当做组件使用时,会在视图构建阶段被调用,适合封装轻量的可复用视图片段(无需完整的组件生命周期)。
类型定义
ts
declare function builder<P extends AnyProps, R extends View>(
builder: (props: P, location?: CodeLocation) => R,
displayName?: string
): ViewBuilder<P, R>参数
| 参数 | 类型 | 说明 |
|---|---|---|
builder | (props: P, location?: CodeLocation) => R | 视图构建函数,location 仅开发时可用 |
displayName | string | 可选的显示名称,被当做组件使用时作为 displayName |
返回值
| 类型 | 说明 |
|---|---|
ViewBuilder<P, R> | 标记后的视图构建器 |
示例
tsx
import { builder } from 'vitarx'
// 标记一个视图构建器
const Button = builder((props, location) => {
return <button {...props}>{props.children}</button>
})
function App() {
// 实际创建出的节点为 <button>按钮</button>
return <Button>按钮</Button>
}对比:构建器在构建阶段展开执行,没有组件实例、生命周期和响应式作用域;需要状态或生命周期时请使用组件。
编译辅助函数
branch()、accessor()、expr() 是 JSX 编译插件 emit 的运行时辅助函数,编译器将模板中的三元表达式、属性访问、动态表达式转换为其调用以获得最优的响应式追踪。手写代码时通常不需要直接使用,但在阅读编译产物或手写 h() 时会遇到。
expr()
运行时判断表达式是否包含响应式依赖:无依赖时直接返回计算值(零开销),有依赖时返回 Ref 自动追踪更新。
tsx
// JSX: <div>{count.value + 1}</div>
// 编译为: createView('div', null, expr(() => count.value + 1))
expr(() => 'hello') // → 'hello'(静态表达式,零开销)
expr(() => count.value) // → Ref<number, never>(包含响应式依赖)accessor()
精确匹配属性访问表达式的辅助,与 expr 的区别在于它会精确匹配 obj.key 形式:对象为响应式时返回 Ref,否则返回静态值。
tsx
// JSX: <div>{data.name}</div>
// 编译为: createView('div', null, accessor(data, 'name'))branch()
分支辅助,将三元/条件表达式转换为按需求值的分支函数,仅在对应分支激活时才创建视图。
tsx
// JSX: <div>{show ? <A /> : <B />}</div>
// 编译为: createView('div', null, branch(() => show.value ? 0 : 1, [() => <A />, () => <B />]))Fragment
片段容器,不渲染额外 DOM 元素,用于返回多个根节点。
Props
ts
interface FragmentProps {
children?: RenderChildren
}| 属性 | 类型 | 说明 |
|---|---|---|
children | RenderChildren | 子节点 |
示例
tsx
import { Fragment } from 'vitarx'
function MultiRoot() {
return (
<Fragment>
<div>First</div>
<div>Second</div>
</Fragment>
)
}Dynamic
动态组件渲染器,根据条件渲染不同的组件。
Props
ts
interface DynamicProps {
is: ViewDescriptor | undefined | null | false
key?: unknown
memo?: boolean | number
children?: RenderChildren
[key: string]: any
}| 属性 | 类型 | 说明 |
|---|---|---|
is | ViewDescriptor | undefined | null | false | 要渲染的组件、标签或视图构建器 |
key | unknown | 可选的缓存 key |
memo | boolean | number | 可选的缓存策略 |
children | RenderChildren | 子节点 |
示例
tsx
import { Dynamic, ref } from 'vitarx'
function App() {
const currentComponent = ref(HomeComponent)
return <Dynamic is={currentComponent} />
}参考:Dynamic 详解
Comment
注释节点,渲染为 HTML 注释。
Props
ts
interface CommentProps {
text: string
}| 属性 | 类型 | 说明 |
|---|---|---|
text | string | 注释文本 |
示例
tsx
import { Comment } from 'vitarx'
function App() {
return (
<div>
<Comment text="section start" />
<div>Content</div>
</div>
)
}PlainText
纯文本节点,直接渲染文本内容。
Props
ts
interface PlainTextProps {
text: string | number
}| 属性 | 类型 | 说明 |
|---|---|---|
text | string | number | 文本内容 |
示例
tsx
import { PlainText } from 'vitarx'
function App() {
return <PlainText text="Hello World" />
}