vue3 tsx组件的几种写法

灯火 Lv4

1.简单函数

1
2
3
4
// child.tsx
cont Child = (msg: string) => {
return <div>msg</div>
}

2. defineComponent 基础使用

1
2
3
4
5
6
7
8
9
10
11
12
13
// child.tsx | child.vue
import { defineComponent } from 'vue';
export default defineComponent({
name: 'Child',
props: {
msg: {
type: String
}
},
setup(props, _ctx) {
return () => <div>{props.msg}</div>
}
})
1
2
3
4
5
6
7
8
9
10
11
12
// child.tsx | child.vue
import { defineComponent } from 'vue';
interface Props {
msg: string
}
// 这种props声明,不知道为什么入参都在attrs里面
export default defineComponent<Props>({
name: 'Child',
setup(props, _ctx) {
return () => <div>{_ctx.attrs.msg}</div>
}
})

3.FunctionalComponent 声明

适合简单的组件【对于从子组件的Events获取的属性可能不存在】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// child.tsx
import { FunctionalComponent } from 'vue';

interface Props {
msg: string
}
// 必须用type声明
type Emit = {
childClick: () => void;
}
const Child: FunctionalComponent<Props, Emit> = (props) => {
console.log('init child')

const formOptions = ref({})
const onSetFormOption = (e) => {
formOptions.value[e[0]] = e[1]
}

const printFormOptions = () => {
// 因为props变更组件重新执行,formOptions属性会重置
console.log(formOptions.value) // {}
}

return (
<div>
<minChild onSet-option={onSetFormOption}/>
<div>{props.msg}</div>
</div>
)
}
export default Child
1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- minChild.vue -->
<template>
<div>最小组件</div>
</template>
<script lang="ts" setup>
const emit = defineEmits(['set-option'])

const getName = () =>{
console.log('min child')
}

emit('set-option',['getName', getName] )
</script>

4.setupSFC

setupSFC | Vue Macros

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Foo.setup.tsx
defineProps<{
foo: string
}>()

defineEmits<{
(evt: 'change'): void
}>()

export default () => (
<div>
<h1>Hello World</h1>
</div>
)

5. setup + tsx

【Vue3干货👍】template setup 和 tsx 的混合开发实践
jsx 中再套一层组件,那scoped就无法透传下去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Counter.vue

<template>
<component :is="render()"></component>
</template>

<script setup lang="tsx">
const props = defineProps<{
count: number;
}>();

const emits = defineEmits(["update:count"]);

const render = () => {
return (
<div>
<div class="content">count is {props.count}</div>
<div>
<button
onClick={() => {
emits("update:count", props.count + 1);
}}
>
add
</button>
</div>
</div>
);
};
</script>

<style lang="less" scoped>
.content {
color: red;
}
</style>


// Parent.vue

<template>
<Counter v-model:count="count" />
</template>

<script setup lang="ts">
import { ref } from "vue";
import Counter from "./views/Counter.vue";

const count = ref(0);
</script>

  • 标题: vue3 tsx组件的几种写法
  • 作者: 灯火
  • 创建于 : 2025-04-12 03:39:27
  • 更新于 : 2025-04-22 02:01:18
  • 链接: https://blog.juniverse.top/2025/04/12/vue3-tsx-write/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论