组件通信
父传子
defineProps
在 Vue 3 中,defineProps 是一个用于在 <script setup> 语法中定义组件的 props 的函数。这个函数提供了一种更加明确和类型安全的方式来定义子组件的 props,使得子父组件之间的数据传递更加清晰和可维护。以下是 defineProps 的基本使用方式:
基本用法:
-
导入
defineProps函数:
首先,你需要从vue包中导入defineProps函数。import { defineProps } from 'vue'; -
使用
defineProps定义 Props:
在<script setup>中,使用defineProps来定义你的组件 props。你可以传递一个对象,对象的属性就是你想要定义的 props,以及它们的类型和验证器。<script setup> import { defineProps } from 'vue'; const props = defineProps({title: String,message: {type: String,default: ''},count: {type: Number,required: true} }); </script>在这个例子中,
title是一个字符串类型的 prop,message是一个带有默认值的字符串类型的 prop,而count是一个必需的数字类型的 prop。 -
在模板中使用 Props:
定义了 props 之后,你可以在组件的模板中像使用数据一样使用它们。<template><div><h1>{{ title }}</h1><p>{{ message }}</p><button @click="count++">Count is: {{ count }}</button></div> </template>
子传父
ref+defineExpose
采用setup模式
在 Vue 3 中,setup 函数是 Composition API 的入口点。它在组件创建之前执行,并且接收两个参数:props 和 context。setup 函数可以返回一个对象,其中的属性和方法将会被暴露给模板或其他 Composition API 函数。
子组件:
父组件:
方法:
- 通过在父组件中去定义
ref变量

- 然后子组件做一个主动暴露

- 父组件通过
.value.方法()的方式拿到子组件提供的方法

- 然后在父组件中就会执行子组件的方法

采用export default模式
在 Vue 2 中,我们通常使用 export default 来定义组件。在 Vue 3 中,虽然 setup 函数是推荐的写法,但仍然可以通过 export default 来定义组件,并且使用 Composition API。
子组件:
父组件:
总结
setup模式:推荐使用,更符合 Vue 3 的设计理念。通过defineExpose明确地控制哪些属性和方法被暴露给父组件或子组件。export default模式:兼容 Vue 2 的写法,可以使用this.$expose来暴露方法,但不是最佳实践。
在实际开发中,推荐使用 setup 模式,因为它提供了更好的类型推断和更清晰的代码结构。
defineEmits
如果你想要实现子组件向父组件传递数据或事件,你应该使用 defineEmits。以下是 defineEmits 的基本用法:
-
导入
defineEmits函数:import { defineEmits } from 'vue'; -
使用
defineEmits定义 emits:
在<script setup>中,使用defineEmits来定义你的组件可以触发的事件。<script setup> import { defineEmits } from 'vue'; const emit = defineEmits(['update', 'click']); </script> -
触发事件:
在子组件中,你可以使用emit函数来触发定义的事件,并向父组件传递数据。<script setup> import { defineEmits } from 'vue'; const emit = defineEmits(['update', 'click']);function someMethod() {emit('update', newValue); } </script> -
在父组件中监听事件:
父组件可以通过v-on或@语法来监听子组件触发的事件。<template><ChildComponent @update="handleUpdate" @click="handleClick" /> </template>
这样,当子组件触发 update 或 click 事件时,父组件的相应方法会被调用,并且可以接收子组件传递的数据。这是 Vue 中实现父子组件通信的一种方式。
defineExpose和defineEmits的区别
defineExpose:defineExpose用于在<script setup>语法糖的组件中明确要暴露出去的属性和方法,使得父组件可以通过ref访问子组件的这些属性和方法。- 它通常用在子组件中,将子组件中的属性或方法暴露给父组件。父组件可以通过
ref获取子组件实例,并直接访问这些暴露的属性和方法。 defineExpose必须在变量和方法声明定义之后使用,否则可能会引起警告甚至页面卡死。
defineEmits:defineEmits用于子组件向父组件传递事件,即子组件可以通过defineEmits声明可以触发的事件,然后在需要的时候触发这些事件,父组件通过监听这些事件来接收数据。- 它允许子组件显式地声明要触发的事件,并在子组件中通过
emits函数触发这些事件,父组件通过监听这些事件来响应。 defineEmits与defineProps一样,只能在<script setup>中使用,并且不需要导入即可使用。
总结来说,defineExpose主要用于子组件向父组件暴露属性和方法,而defineEmits主要用于子组件向父组件传递事件。两者都是Vue 3中组件间通信的重要工具,但它们的使用场景和目的有所不同。
