vue3第三部分--组件通信
title: 组件通信 date: 2025-01-28 12:00:00 tags: - 前端 categories: - 前端
组件通信
目标:重点学习父子组件与兄弟组件的通信方式,以及插槽的作用与使用方式
父子组件通信
主要是通过props和自定义事件来实现
1.1 父 -> 子通信(通过 Props)
父组件通过 props 将数据传递给子组件。
父组件
<template> <ChildComponent :message="parentMessage" /> </template> <script setup> import ChildComponent from './ChildComponent.vue' const parentMessage = "Hello from Parent" </script>
子组件
<template> <p>{ { message }}</p> </template> <script setup> defineProps(['message']) </script>
• 父组件通过 :message 将数据传递给子组件。
• 子组件使用 defineProps 接收父组件传递的 message。
1.2 子 -> 父通信(通过自定义事件)
子组件通过 $emit 触发事件,将数据发送给父组件。
父组件--
<template> <ChildComponent @sendMessage="receiveMessage" /> <p>父组件收到的消息:{ { message }}</p> </template> <script setup> import ChildComponent from './ChildComponent.vue' import { ref } from 'vue' const message = ref('') function receiveMessage(data) { message.value = data } </script>
子组件--
<template> <button @click="sendToParent">发送消息给父组件</button> </template> <script setup> import { ref } from 'vue' const childMessage = ref('Hello from Child') function sendToParent() { // 触发自定义事件,传递数据 emit('sendMessage', childMessage.value) } defineEmits(['sendMessage']) </script>
• 作用:
• 子组件通过 $emit 向父组件发送消息。
• 父组件通过 @sendMessage 监听子组件的事件,并处理接收到的数据。
2. 兄弟组件通信
兄弟组件之间的通信不能直接进行,需要通过 状态管理工具(如 Pinia、Vuex) 或 事件总线。
2.1 使用 Pinia(推荐方式)
Pinia 是 Vue 3 中推荐的状态管理工具。
定义一个store
// stores/messageStore.js import { defineStore } from 'pinia' export const useMessageStore = defineStore('messageStore', { state: () => ({ message: '' }), actions: { setMessage(newMessage) { this.message = newMessage } } })
兄弟组件 A(发送数据)
<template> <button @click="sendMessage">发送消息</button> </template> <script setup> import { useMessageStore } from '@/stores/messageStore' const messageStore = useMessageStore() function sendMessage() { messageStore.setMessage('Hello from Component A') } </script>
兄弟组件 B(接收数据)
<template> <p>接收到的消息:{ { message }}</p> </template> <script setup> import { useMessageStore } from '@/stores/messageStore' const messageStore = useMessageStore() const message = computed(() => messageStore.message) </script>
使用 Pinia Store 作为共享状态,兄弟组件可以方便地访问和更新数据。
3. 插槽(Slots)
插槽是 Vue 中的一种机制,用于实现父组件向子组件传递 HTML 结构或动态内容。
3.1 基础插槽
父组件向子组件插入内容。
子组件
<template> <div class="box"> <slot></slot> <!-- 占位符 --> </div> </template> <script setup></script> <style> .box { padding: 10px; border: 1px solid black; } </style>
父组件
<template> <ChildComponent> <p>这是插槽内容</p> </ChildComponent> </template> <script setup> import ChildComponent from './ChildComponent.vue' </script>
父组件通过 <slot 将自定义内容插入到子组件中。
3.2 具名插槽
可以通过命名插槽向子组件的不同部分插入内容。
子组件
<template> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </template>
父组件
<template> <ChildComponent> <template #header> <h1>这是头部内容</h1> </template> <p>这是默认插槽内容</p> <template #footer> <p>这是底部内容</p> </template> </ChildComponent> </template>
3.3 作用域插槽
子组件将数据传递给插槽内容,父组件可以根据这些数据动态渲染内容。
<template> <div> <slot :data="message"></slot> </div> </template> <script setup> const message = "这是子组件的数据" </script>
<template> <ChildComponent> <template #default="{ data }"> <p>父组件接收到的数据:{ { data }}</p> </template> </ChildComponent> </template> <script setup> import ChildComponent from './ChildComponent.vue' </script>
子组件通过 slot 的 props 将数据传递给父组件。
• 父组件可以动态展示这些数据。