Vue 组件通信方式总览
Vue 中,组件通信有很多种方式,适合不同的场景。
我给你系统地总结一版,方法 + 场景 + 简单例子,非常清晰直白!👇
📦 Vue 组件通信方式总览
通信方式 | 适合场景 | 简单描述 |
---|---|---|
props + emit | 父子组件传值 | 父传数据给子,子触发事件通知父 |
v-model | 父子双向绑定 | 父和子同步更新数据 |
provide / inject | 祖孙组件传值 | 父(祖先)提供数据,任意后代组件注入 |
eventBus (小项目) | 跨级、兄弟通信 | 通过一个中央事件总线来发消息监听 |
Pinia (或 Vuex) | 大项目全局共享 | 状态管理工具,统一管理数据 |
ref + defineExpose | 父拿到子的方法或数据 | 父通过 ref 直接操作子组件 |
slots 插槽 | 传模板内容 | 父把结构/内容传给子 |
🔥 主要的用法举例
1. props
+ emit
(父子通信)
父传子:props
<Child :msg="parentMsg" />
子组件
<script setup>
defineProps(['msg'])
</script>
子传父:emit
<Child @submit="handleSubmit" />
子组件
<script setup>
const emit = defineEmits(['submit'])function submit() {emit('submit', '子组件传给父的数据')
}
</script>
2. v-model
(父子双向绑定)
父子组件同步一份数据!
父组件
<Child v-model="username" />
子组件
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])function updateValue(e) {emit('update:modelValue', e.target.value)
}
</script>
3. provide
/ inject
(祖孙通信)
祖先组件提供
<script setup>
import { provide } from 'vue'
provide('userInfo', { name: 'Tom', age: 20 })
</script>
任意子孙组件注入
<script setup>
import { inject } from 'vue'
const user = inject('userInfo')
console.log(user)
</script>
4. 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)
})
5. Pinia
状态管理(大型项目推荐)
统一管理全局数据。
import { defineStore } from 'pinia'export const useUserStore = defineStore('user', {state: () => ({username: 'Tom'}),actions: {updateName(newName) {this.username = newName}}
})
然后各个组件都可以直接使用。
6. ref
+ defineExpose
(父拿子组件方法或数据)
子组件
<script setup>
import { ref } from 'vue'
const count = ref(0)function add() {count.value++
}defineExpose({ count, add })
</script>
父组件
<template><Child ref="childRef" /><button @click="childRef.add()">增加</button>
</template><script setup>
import { ref } from 'vue'
import Child from './Child.vue'const childRef = ref()
</script>
🎯 总结
通信场景 | 推荐方法 |
---|---|
父子 | props + emit |
父子双向绑定 | v-model |
祖孙 | provide / inject |
兄弟 | eventBus |
跨越整个项目 | Pinia |
父直接操控子 | ref + defineExpose |
内容传递 | slot |
🚀 一句话记住
小项目:props/emit/eventBus,大项目:Pinia,全局管理;祖孙:provide/inject;复杂逻辑:ref + expose。