Vue 的传值方式(即组件之间的数据通信方式)根据组件关系不同(父子、兄弟、跨层级)有所区别。下面是常见的传值方式,按使用场景来分类:
一、父子组件传值
1. props(父 -> 子)
 
父组件通过 props 向子组件传递数据。
<!-- 父组件 -->
<Child :msg="parentMsg" /><!-- 子组件 -->
props: ['msg']
 
2. $emit(子 -> 父)
 
子组件通过 $emit 触发自定义事件,向父组件传递数据。
<!-- 子组件 -->
this.$emit('updateData', newValue)<!-- 父组件 -->
<Child @updateData="handleUpdate" />
 
二、兄弟组件传值
兄弟组件没有直接的父子关系,需通过事件总线或状态管理来中转:
3. 事件总线(Vue 2 常用)
创建一个空的 Vue 实例作为事件总线。
// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()// 组件A
EventBus.$emit('sendData', data)// 组件B
EventBus.$on('sendData', (data) => { /* 接收数据 */ })
 
Vue 3 中不推荐使用事件总线,可以考虑
mitt或其他方式。
4. 状态管理(Vuex 或 Pinia)
使用状态管理工具集中管理数据,适合大中型项目。
// 示例:Pinia
const store = useMainStore()
store.data = 'xxx'
 
三、跨层级传值
5. provide / inject
 
祖先组件使用 provide,后代组件用 inject 接收。适合深层嵌套组件传值。
// 祖先组件
provide('theme', 'dark')// 后代组件
inject('theme') // 得到 'dark'
 
四、非组件通信
6. URL 参数 / 路由参数
通过 vue-router 的 query 或 params 传递数据。
// query 传值
this.$router.push({ path: '/page', query: { id: 123 } })// 接收
this.$route.query.id// params 传值(需配置动态路由)
this.$router.push({ name: 'page', params: { id: 123 } })
 
五、Ref 引用方式(Vue 3 特性)
7. ref + expose(父调用子)
 
子组件通过 defineExpose 暴露方法或数据,供父组件访问。
// 子组件
defineExpose({ childMethod })// 父组件
const childRef = ref()
childRef.value.childMethod()