项目中经常遇到的数据传递方式进行了一个小结:
1. Props 和 Events(父子组件间)
- Props:父组件通过 props 向子组件传递数据。
// 父组件
<template>
<ChildComponent :message="parentMessage" />
</template>
<script>
export default {
data() {
return {
parentMessage: 'Hello from Parent'
};
}
};
</script>
- Events:子组件通过
$emit
触发事件,父组件监听并获取数据。
// 子组件
<template>
<button @click="sendData">Send Data</button>
</template>
<script>
export default {
methods: {
sendData() {
this.$emit('dataSent', 'Hello from Child');
}
}
};
</script>
// 父组件
<template>
<ChildComponent @dataSent="handleData" />
</template>
<script>
export default {
methods: {
handleData(data) {
console.log(data);
}
}
};
</script>
2. Provide 和 Inject(祖孙组件间)
- Provide:在祖先组件中提供数据。
- Inject:在后代组件中注入数据。
// 祖先组件
<template>
<ChildComponent />
</template>
<script>
export default {
provide() {
return {
sharedData: 'Hello from Ancestor'
};
}
};
</script>
// 后代组件
<template>
<div>{{ injectedData }}</div>
</template>
<script>
export default {
inject: ['sharedData'],
computed: {
injectedData() {
return this.sharedData;
}
}
};
</script>
3. Composition API(组合式 API)
使用 Composition API,可以通过 ref
和 reactive
来管理状态,并通过函数返回这些状态。
import { ref } from 'vue';
export function useSharedState() {
const count = ref(0);
function increment() {
count.value++;
}
return { count, increment };
}
// 组件中使用
<template>
<button @click="increment">{{ count }}</button>
</template>
<script>
import { useSharedState } from './useSharedState';
export default {
setup() {
const { count, increment } = useSharedState();
return { count, increment };
}
};
</script>
4. Event Bus(事件总线)
在某些情况下,可以使用事件总线来实现组件之间的通信,但在 Vue 3 中,推荐使用更现代的状态管理方案(如 Vuex 或 Pinia)。
// eventBus.js
import { reactive } from 'vue';
const eventBus = reactive({});
export default eventBus;
// 发送事件
eventBus.someEvent = 'data';
// 监听事件
const data = eventBus.someEvent;
5. Vuex 或 Pinia(状态管理)
对于大型应用,使用 Vuex 或 Pinia 进行全局状态管理是最佳选择。
// Vuex store
import { createStore } from 'vuex';
const store = createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
}
});
// 组件中使用
<template>
<button @click="increment">{{ count }}</button>
</template>
<script>
import { useStore } from 'vuex';
export default {
setup() {
const store = useStore();
return {
count: store.state.count,
increment: () => store.commit('increment')
};
}
};
</script>
总结
在 Vue 中,数据传递的方式多样且灵活。可以根据具体的需求选择合适的方式。对于简单的父子组件通信,使用 props 和 events 就足够了;而对于复杂的状态管理,推荐使用 Vuex 或 Pinia。