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()