Vue 组件通信详解
组件通信的重要性
在 Vue 应用中,组件通信是一个核心概念,良好的组件通信机制可以让应用更容易维护和扩展。
Props 父子组件通信
父组件传递数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <!-- 父组件 --> <template> <child-component :message="message" :user="user" /> </template>
<script setup> import { ref, reactive } from 'vue'
const message = ref('Hello from parent') const user = reactive({ name: 'John', age: 25 }) </script>
|
子组件接收数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <!-- 子组件 --> <template> <div> <p>{{ message }}</p> <p>{{ user.name }}</p> </div> </template>
<script setup> defineProps({ message: String, user: Object }) </script>
|
Emits 子父组件通信
子组件触发事件
1 2 3 4 5 6 7 8 9 10 11
| <template> <button @click="handleClick">Click Me</button> </template>
<script setup> const emit = defineEmits(['update', 'delete'])
const handleClick = () => { emit('update', { id: 1, data: 'new data' }) } </script>
|
父组件监听事件
1 2 3 4 5 6
| <template> <child-component @update="handleUpdate" @delete="handleDelete" /> </template>
|
依赖注入 Provide/Inject
父组件提供数据
1 2 3 4 5 6
| <script setup> import { provide, ref } from 'vue'
const theme = ref('dark') provide('theme', theme) </script>
|
子组件注入数据
1 2 3 4 5
| <script setup> import { inject } from 'vue'
const theme = inject('theme', 'light') // 第二个参数是默认值 </script>
|
事件总线
虽然 Vue 3 移除了全局事件总线,但我们可以使用 mitt 库实现:
1 2 3 4 5 6 7 8 9 10 11 12 13
| import mitt from 'mitt' export default mitt()
import eventBus from './eventBus' eventBus.emit('custom-event', { data: 'hello' })
import eventBus from './eventBus' eventBus.on('custom-event', (data) => { console.log(data) })
|
Vuex/Pinia 状态管理
对于大型应用,推荐使用状态管理库:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', { state: () => ({ name: 'John', isAdmin: false }), actions: { updateName(name) { this.name = name } } })
|
最佳实践建议
- 优先使用 props 和 emits 进行父子组件通信
- 对于深层组件通信,考虑使用依赖注入
- 复杂状态管理场景,使用 Pinia
- 避免过度使用全局状态
- 保持数据流的可预测性
提示:选择合适的通信方式对于构建可维护的 Vue 应用至关重要。根据具体场景选择最适合的通信方式。