主题
函数式组件
显式 functional SFC
vue
<script lang="jsx">
export default {
name: 'FunctionalSfcJsx',
functional: true,
props: { text: String },
render(h, context) {
return (
<article {...context.data} class={['demo-card', context.data.class]}>
<span class="case-label">functional SFC / JSX</span>
<h3>{context.props.text}</h3>
<p>显式 functional: true,使用 context.props、context.data 与 children。</p>
{context.children}
</article>
)
}
}
</script>vue
<script lang="tsx">
type FunctionalContext = {
props: { text: string; count: number }
data: Record<string, unknown>
}
export default {
name: 'FunctionalSfcTsx',
functional: true,
props: {
text: { type: String, default: '' },
count: { type: Number, default: 0 }
},
render(h: any, context: FunctionalContext) {
return (
<article class="demo-card">
<span class="case-label">functional SFC / TSX</span>
<h3>{context.props.text}</h3>
<p>带类型的 functional render,当前外部计数:{context.props.count}</p>
</article>
)
}
}
</script>箭头函数语法糖
大写变量名、箭头函数、直接返回 JSX 的声明会转换为 { functional: true, render }。
jsx
export const FunctionalArrowJsx = ({ props, listeners }) => (
<article class="demo-card compact-card">
<span class="case-label">functional sugar / JSX</span>
<h3>{props.label}</h3>
<button class="button" onClick={listeners.activate}>触发父组件事件</button>
</article>
)tsx
type ArrowContext = {
props: { label: string; value: number }
}
export const FunctionalArrowTsx = ({ props }: ArrowContext) => (
<article class="demo-card compact-card">
<span class="case-label">functional sugar / TSX</span>
<h3>{props.label}</h3>
<p>类型化 props value:{props.value}</p>
</article>
)普通 items.map(item => <li />) 不会被误判为 functional component。