在Vue3中,组件间数据传输主要有以下几种方式:
1. Props(父传子)
父组件通过属性绑定向子组件传递数据:
vue
<!-- 父组件 -->
<Child :title="pageTitle" :count="counter" />
<!-- 子组件 -->
<script setup>
const props = defineProps({
title: String,
count: Number
})
console.log(props.title) // 使用数据
</script>
2. Emit(子传父)
子组件通过事件向父组件传递数据:
vue
<!-- 子组件 -->
<button @click="$emit('update', newValue)">提交</button>
<!-- 父组件 -->
<Child @update="handleUpdate" />
<script setup>
function handleUpdate(value) {
console.log('收到子组件数据:', value)
}
</script>
3. ref获取组件实例
父组件直接访问子组件数据:
vue
<!-- 父组件 -->
<Child ref="childRef" />
<button @click="getChildData">获取</button>
<script setup>
import { ref } from 'vue'
const childRef = ref(null)
function getChildData() {
console.log(childRef.value.childData)
}
</script>
4. Provide/Inject(跨级传递)
祖先组件提供数据:
javascript
// 祖先组件
import { provide } from 'vue'
provide('theme', 'dark')
后代组件注入数据:
javascript
// 后代组件
import { inject } from 'vue'
const theme = inject('theme')
5. 状态管理(Pinia)
复杂场景使用状态管理库:
javascript
// store/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++
}
}
})
vue
<!-- 组件中使用 -->
<script setup>
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
</script>
<template>
<button @click="counter.increment()">{{ counter.count }}</button>
</template>
6. 事件总线(Event Bus)
使用第三方库实现全局事件:
javascript
// eventBus.js
import mitt from 'mitt'
export const emitter = mitt()
javascript
// 组件A
emitter.emit('message', 'Hello')
// 组件B
emitter.on('message', (msg) => {
console.log(msg) // 输出: Hello
})
根据场景选择合适的数据传递方式:
- 简单父子通信:Props/Emit
- 跨层级传递:Provide/Inject
- 复杂应用状态:Pinia
- 全局事件:事件总线
注意:Vue3推荐使用Composition API的setup语法糖,所有示例均采用该写法。