Vue 3 引入了Composition API,为组件间通信带来了新的思路和灵活性,但传统的props用于父向子传递数据和emits用于子向父通知的方式依然保留并得到改进,确保了组件间通信的清晰与高效。下面详细介绍Vue 3中如何使用props和emits进行父子组件间的数据传递。

Props:父组件向子组件传递数据

在Vue 3中,props的工作原理基本保持不变,但使用Composition API定义和接收props的方式有所变化。

父组件中定义Props

父组件通过属性绑定的方式将数据传递给子组件,例如:

<template>
  <ChildComponent :message="parentMessage" />
</template>

<script setup>
import ChildComponent from './ChildComponent.vue';
const parentMessage = 'Hello from Parent!';
</script>

在这里,:message就是将parentMessage的值传递给了子组件的message prop。

子组件中接收Props

子组件中使用defineProps来接收父组件传递的props,无需在组件选项中显式声明props。

<template>
  <p>{{ message }}</p>
</template>

<script setup>
const props = defineProps(['message']);
</script>

defineProps是一个函数,接收一个数组或对象来定义props的名称和类型(可选)。上述代码展示了最基本的形式,直接接收一个数组,数组中的每个字符串元素代表一个prop的名称。

Emits:子组件向父组件发送事件

Vue 3中使用defineEmits来声明组件可能发出的事件,以此实现子组件向父组件的通知。

子组件中定义Emits

在子组件内部,使用defineEmits来定义可能触发的事件列表:

<template>
  <button @click="emit('customEvent', someData)">Click Me</button>
</template>

<script setup>
const emit = defineEmits(['customEvent']);
const someData = 'Data to be sent with event';
</script>

这里,defineEmits接收一个数组,数组中的每个字符串元素代表一个事件的名称。然后,通过emit函数在适当的时候触发这些事件,并可以携带额外的数据。

父组件中监听子组件的事件

父组件通过在子组件标签上使用v-on或@来监听子组件发出的事件,并定义响应逻辑:

<template>
  <ChildComponent @customEvent="handleCustomEvent" />
</template>

<script setup>
import ChildComponent from './ChildComponent.vue';

function handleCustomEvent(data) {
  console.log('Received data:', data);
}
</script>

当子组件触发customEvent时,父组件的handleCustomEvent方法会被调用,传递的数据也会随之而来。

总结

Vue 3中,通过defineProps和defineEmits,使得组件间通信更加简洁明了,同时也保持了Vue一直以来的响应式特性。这种模式强化了单向数据流的概念,即父组件通过props向下传递数据,子组件通过emits触发事件向上通知变化,确保了组件间的清晰边界和易于维护的代码结构。在实际应用中,根据具体需求灵活运用这两种机制,可以构建出既高效又可维护的Vue应用程序。