主题
SFC 局部 JSX/TSX
局部使用 JSX 不要求整个 SFC 都改成 render。外层可以继续使用 template,只在 script 中声明并注册局部 JSX 子组件。
template + 局部 JSX
vue
<template>
<article class="demo-card">
<span class="case-label">局部 JSX + template</span>
<h3>LocalJsxInSfc.vue</h3>
<LocalBadge :text="message" />
<p>外层仍使用 template,局部子组件在 script lang="jsx" 中使用 JSX。</p>
<button class="button" @click="count += 1">更新局部 JSX:{{ count }}</button>
</article>
</template>
<script lang="jsx">
const LocalBadge = {
name: 'LocalJsxBadge',
functional: true,
props: { text: String },
render(h, { props }) {
return <span class="badge">{props.text}</span>
}
}
export default {
name: 'LocalJsxInSfc',
components: { LocalBadge },
data() {
return { count: 0 }
},
computed: {
message() {
return `局部 JSX 计数:${this.count}`
}
}
}
</script>template + 局部 TSX
vue
<template>
<article class="demo-card">
<span class="case-label">局部 TSX + template</span>
<h3>LocalTsxInSfc.vue</h3>
<LocalMetric :label="label" :value="value" />
<p>局部函数式子组件带 TypeScript 类型,外层仍是普通 Vue 模板。</p>
<button class="button" @click="value += 1">value + 1</button>
</article>
</template>
<script lang="tsx">
type MetricContext = {
props: { label: string; value: number }
}
const LocalMetric = ({ props }: MetricContext) => (
<span class="metric">
<small>{props.label}</small>
<strong>{props.value}</strong>
</span>
)
export default {
name: 'LocalTsxInSfc',
components: { LocalMetric },
data(): { label: string; value: number } {
return { label: '局部 TSX', value: 7 }
}
}
</script>这种模式适合表格单元格、局部图标、动态内容渲染器等需要 JSX 表达力,但仍希望保留 template 可读性的组件。