Vue 中,组件通信有很多种方式,适合不同的场景。
我给你系统地总结一版,方法 + 场景 + 简单例子,非常清晰直白!
通信方式 | 适合场景 | 简单描述 |
---|---|---|
props + emit |
父子组件传值 | 父传数据给子,子触发事件通知父 |
v-model |
父子双向绑定 | 父和子同步更新数据 |
provide / inject |
祖孙组件传值 | 父(祖先)提供数据,任意后代组件注入 |
eventBus (小项目) |
跨级、兄弟通信 | 通过一个中央事件总线来发消息监听 |
Pinia (或 Vuex) |
大项目全局共享 | 状态管理工具,统一管理数据 |
ref + defineExpose |
父拿到子的方法或数据 | 父通过 ref 直接操作子组件 |
slots 插槽 |
传模板内容 | 父把结构/内容传给子 |
props
+ emit
(父子通信)父传子:props
子组件
子传父:emit
子组件
v-model
(父子双向绑定)父子组件同步一份数据!
父组件
子组件
provide
/ inject
(祖孙通信)祖先组件提供
任意子孙组件注入
eventBus
(适合兄弟通信,小项目用)手动创建一个简单的事件中心:
// eventBus.js
import mitt from 'mitt'
export const eventBus = mitt()
发送事件
import { eventBus } from './eventBus'
eventBus.emit('eventName', payload)
监听事件
import { eventBus } from './eventBus'
eventBus.on('eventName', (payload) => {
console.log(payload)
})
Pinia
状态管理(大型项目推荐)统一管理全局数据。
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
username: 'Tom'
}),
actions: {
updateName(newName) {
this.username = newName
}
}
})
然后各个组件都可以直接使用。
ref
+ defineExpose
(父拿子组件方法或数据)子组件
父组件
通信场景 | 推荐方法 |
---|---|
父子 | props + emit |
父子双向绑定 | v-model |
祖孙 | provide / inject |
兄弟 | eventBus |
跨越整个项目 | Pinia |
父直接操控子 | ref + defineExpose |
内容传递 | slot |
小项目:props/emit/eventBus,大项目:Pinia,全局管理;祖孙:provide/inject;复杂逻辑:ref + expose。