在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定义明确的类型。