组件通信
父传子
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中组件间通信的重要工具,但它们的使用场景和目的有所不同。