在Vue 3中使用TypeScript进行组件间传参是开发中常见的需求,它能提供类型安全和更好的开发体验。以下是Vue 3 + TypeScript组件传参的详细教程:
1. 父组件向子组件传参(Props)
子组件定义Props类型
使用defineProps宏函数并指定类型:
<!-- ChildComponent.vue -->
<template>
<div>
<p>姓名: {
{ name }}</p>
<p>年龄: {
{ age }}</p>
<p>爱好: {
{ hobbies.join(', ') }}</p>
</div>
</template>
<script setup lang="ts">
// 定义props类型
interface Props {
name: string;
age: number;
hobbies?: string[]; // 可选属性
}
// 使用defineProps定义并指定类型
const props = defineProps<Props>();
// 也可以直接在defineProps中定义类型
// const props = defineProps<{
// name: string;
// age: number;
// hobbies?: string[];
// }>();
</script>
父组件传递参数
<!-- ParentComponent.vue -->
<template>
<ChildComponent
:name="userName"
:age="userAge"
:hobbies="userHobbies"
/>
</template>
<script setup lang="ts">
import ChildComponent from './ChildComponent.vue';
const userName = "张三";
const userAge = 25;
const userHobbies = ["读书", "运动"];
</script>
2. 子组件向父组件传参(Emits)
子组件定义Emits类型
<!-- ChildComponent.vue -->
<template>
<button @click="handleClick">点击发送事件</button>
</template>
<script setup lang="ts">
// 定义emits类型
const emit = defineEmits<{
(e: 'change', value: string): void;
(e: 'update', id: number, status: boolean): void;
}>();
const handleClick = () => {
// 触发事件并传递参数
emit('change', '这是传递的字符串');
emit('update', 123, true);
};
</script>
父组件接收事件
<!-- ParentComponent.vue -->
<template>
<ChildComponent
@change="handleChange"
@update="handleUpdate"
/>
</template>
<script setup lang="ts">
import ChildComponent from './ChildComponent.vue';
const handleChange = (value: string) => {
console.log('收到子组件消息:', value);
};
const handleUpdate = (id: number, status: boolean) => {
console.log('收到更新事件:', id, status);
};
</script>
3. 双向绑定(v-model)
子组件实现v-model
<!-- ChildComponent.vue -->
<template>
<input
type="text"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</template>
<script setup lang="ts">
// 定义v-model的类型
const props = defineProps<{
modelValue: string;
}>();
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void;
}>();
</script>
父组件使用v-model
<!-- ParentComponent.vue -->
<template>
<ChildComponent v-model="message" />
<p>父组件的值: {
{ message }}</p>
</template>
<script setup lang="ts">
import ChildComponent from './ChildComponent.vue';
import { ref } from 'vue';
const message = ref("初始值");
</script>
4. 多个v-model绑定
<!-- ChildComponent.vue -->
<template>
<input
type="text"
:value="name"
@input="$emit('update:name', $event.target.value)"
/>
<input
type="number"
:value="age"
@input="$emit('update:age', Number($event.target.value))"
/>
</template>
<script setup lang="ts">
const props = defineProps<{
name: string;
age: number;
}>();
const emit = defineEmits<{
(e: 'update:name', value: string): void;
(e: 'update:age', value: number): void;
}>();
</script>
父组件使用:
<ChildComponent
v-model:name="userName"
v-model:age="userAge"
/>
5. 透传属性(Attrs)
当需要传递未在props中定义的属性时,可以使用useAttrs:
<script setup lang="ts">
import { useAttrs } from 'vue';
const attrs = useAttrs();
// attrs包含所有未在props中声明的属性
console.log(attrs);
</script>
总结
Vue 3 + TypeScript的传参方式主要有:
- Props:父向子传递数据
- Emits:子向父传递事件和数据
- v-model:双向绑定
- useAttrs:透传未声明的属性
使用TypeScript可以在编译阶段就发现类型错误,提高代码质量和开发效率。在实际开发中,建议为所有props和emits定义明确的类型。