简化版 JSX 支持
Zhin.js 提供简化版的 JSX 语法,专注于核心组件功能,不生成 HTML 标签。
🚀 快速开始
1. 导入 JSX 运行时
typescript
import { jsx, jsxs, Fragment, renderJSX } from '@zhin.js/core/jsx';
import { Container, Text, Title, List, Card } from '@zhin.js/core';📝 基本用法
创建 JSX 元素
typescript
// 基础 JSX
const element = jsx(Container, {
title: '欢迎',
children: [
jsx(Title, { children: '欢迎使用 JSX!', level: 1 }),
jsx(Text, { children: '这是一个使用 JSX 语法的组件示例。' }),
jsx(Card, {
header: '提示',
children: '这是卡片内容'
})
]
});
// 渲染 JSX 元素
const result = await renderJSX(element, context);使用 Fragment
typescript
const fragment = jsx(Fragment, {
children: [
jsx(Text, { children: '第一段' }),
jsx(Text, { children: '第二段' }),
jsx(Text, { children: '第三段' })
]
});🎨 内置组件
Zhin.js 提供简化的内置 JSX 组件:
容器组件
typescript
// 容器
jsx(Container, {
title: '标题',
children: '内容'
});
// 文本
jsx(Text, {
bold: true,
children: '粗体文本'
});
// 标题
jsx(Title, {
level: 2,
children: '二级标题'
});列表组件
typescript
// 列表
jsx(List, {
items: ['项目1', '项目2', '项目3']
});
// 卡片
jsx(Card, {
header: '卡片标题',
children: '卡片内容'
});🔧 自定义组件
创建 JSX 函数组件
typescript
const UserCard = (props: { user: { name: string; age: number; avatar?: string } }, context?: ComponentContext) => {
const { user } = props;
return jsx(Div, {
className: 'user-card',
children: [
user.avatar ? jsx(Img, { src: user.avatar, alt: user.name, className: 'avatar' }) : null,
jsx(Div, {
className: 'user-info',
children: [
jsx(H3, { children: user.name }),
jsx(P, { children: `年龄: ${user.age}` })
]
})
]
});
};使用自定义组件
typescript
const user = { name: '张三', age: 25, avatar: 'avatar.jpg' };
const userCard = jsx(UserCard, { user });
const html = await renderJSX(userCard, context);🎯 高级特性
条件渲染
typescript
const ConditionalComponent = (props: { show: boolean }) => {
return jsx(Div, {
children: props.show ?
jsx(H1, { children: '显示标题' }) :
jsx(P, { children: '隐藏标题' })
});
};列表渲染
typescript
const ListComponent = (props: { items: string[] }) => {
return jsx(Div, {
className: 'list',
children: props.items.map((item, index) =>
jsx(Div, {
key: index,
className: 'list-item',
children: jsx(Span, { children: item })
})
)
});
};嵌套组件
typescript
const Layout = (props: { children: JSXChildren }) => {
return jsx(Div, {
className: 'layout',
children: [
jsx(Div, {
className: 'header',
children: jsx(H1, { children: '页面标题' })
}),
jsx(Div, {
className: 'content',
children: props.children
})
]
});
};🔄 与模板系统集成
JSX 组件可以与现有的模板系统无缝集成:
typescript
// 在模板中使用 JSX 组件
const template = `
<div class="page">
<user-card user={user} />
<div class="content">
${await renderJSX(jsx(P, { children: '动态内容' }), context)}
</div>
</div>
`;📚 类型支持
JSX 类型定义
typescript
import { JSXElement, JSXChildren, JSXFunctionComponent } from '@zhin.js/core/jsx';
// JSX 元素类型
const element: JSXElement = jsx(Div, { children: 'Hello' });
// JSX 子元素类型
const children: JSXChildren = [
'文本',
jsx(Span, { children: '组件' }),
null,
undefined
];
// JSX 函数组件类型
const MyComponent: JSXFunctionComponent<{ title: string }> = (props, context) => {
return jsx(H1, { children: props.title });
};🎨 样式支持
内联样式
typescript
jsx(Div, {
style: 'padding: 20px; background: #f0f0f0; border-radius: 8px;',
children: '带样式的容器'
});CSS 类名
typescript
jsx(Button, {
className: 'btn btn-primary btn-lg',
children: '大按钮'
});动态样式
typescript
const DynamicButton = (props: { variant: 'primary' | 'secondary' }) => {
const className = `btn btn-${props.variant}`;
return jsx(Button, {
className,
children: '动态按钮'
});
};🚀 最佳实践
1. 组件命名
typescript
// 使用 PascalCase 命名组件
const UserProfile = (props: UserProfileProps) => { /* ... */ };
const ProductCard = (props: ProductCardProps) => { /* ... */ };2. Props 类型定义
typescript
interface UserCardProps {
user: {
name: string;
age: number;
avatar?: string;
};
className?: string;
style?: string;
}
const UserCard: JSXFunctionComponent<UserCardProps> = (props, context) => {
// 组件实现
};3. 错误处理
typescript
const SafeComponent = (props: { data: any }) => {
try {
return jsx(Div, {
children: jsx(P, { children: props.data.message })
});
} catch (error) {
return jsx(Div, {
className: 'error',
children: jsx(P, { children: '加载失败' })
});
}
};🔧 调试技巧
1. 查看 JSX 元素结构
typescript
console.log('JSX 元素:', JSON.stringify(element, null, 2));2. 逐步渲染
typescript
const step1 = jsx(Div, { children: '第一步' });
const step2 = jsx(Div, { children: '第二步' });
const combined = jsx(Div, {
children: [step1, step2]
});📖 总结
JSX 支持让 Zhin.js 的组件开发更加现代化和直观:
- ✅ 直观的语法 - 类似 React 的 JSX 语法
- ✅ 完整的类型支持 - TypeScript 类型检查
- ✅ 丰富的内置组件 - Div、Span、P、H1-H3、Button、Img 等
- ✅ 自定义组件 - 支持函数式组件
- ✅ 模板集成 - 与现有模板系统无缝集成
- ✅ 异步支持 - 支持异步组件渲染
现在你可以使用熟悉的 JSX 语法来开发 Zhin.js 组件了!🎉