在Vue 3中,组件间通信的方式可以分为两大类:选项式API(Options API)和组合式API(Composition API)。每种API风格都有其特点和适用场景,下面将分别介绍这两种API风格下的组件间通信方法。
选项式API(Options API)
1. props
与emit
props用于父组件向子组件传递数据,而emit用于子组件向父组件传递数据。
父组件:
<template>
<ChildComponent :message="parentMessage" @childEvent="handleChildEvent" />
</template>
<script>
export default {
data() {
return {
parentMessage: 'Hello from Parent'
};
},
methods: {
handleChildEvent(message) {
console.log(message); // 输出: Hello from Child
}
}
};
</script>
子组件:
<template>
<div>
<p>{{ message }}</p>
<button @click="sendToParent">Send to Parent</button>
</div>
</template>
<script>
export default {
props: ['message'],
methods: {
sendToParent() {
this.$emit('childEvent', 'Hello from Child');
}
}
};
</script>
2. provide
与inject
provide和inject用于祖先组件向其所有后代组件提供数据。
祖先组件:
<template>
<ChildComponent />
</template>
<script>
export default {
provide() {
return {
theme: 'dark'
};
}
};
</script>
后代组件:
<template>
<p>The current theme is {{ theme }}</p>
</template>
<script>
export default {
inject: ['theme']
};
</script>
3. ref
父组件可以通过ref
属性来访问子组件的实例,从而直接调用子组件的方法或访问其属性。
父组件:
<template>
<ChildComponent ref="childRef" />
</template>
<script>
export default {
mounted() {
this.$refs.childRef.someMethod(); // 假设子组件有一个someMethod方法
}
};
</script>
子组件:
<template>
<p>Hello from Child</p>
</template>
<script>
export default {
methods: {
someMethod() {
console.log('Called from Parent');
}
}
};
</script>
组合式API(Composition API)
1. props
与emit
父组件:
<template>
<ChildComponent :message="parentMessage" @childEvent="handleChildEvent" />
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const parentMessage = ref('Hello from Parent');
function handleChildEvent(message) {
console.log(message); // 输出: Hello from Child
}
</script>
子组件:
<template>
<div>
<p>{{ message }}</p>
<button @click="sendToParent">Send to Parent</button>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
message: String
});
const emit = defineEmits(['childEvent']);
function sendToParent() {
emit('childEvent', 'Hello from Child');
}
</script>
2. provide
与inject
祖先组件:
<template>
<ChildComponent />
</template>
<script setup>
import { provide, ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const theme = ref('dark');
provide('theme', theme);
</script>
后代组件:
<template>
<p>The current theme is {{ theme }}</p>
</template>
<script setup>
import { inject } from 'vue';
const theme = inject('theme');
</script>
3. ref
父组件可以通过ref
属性来访问子组件的实例,从而直接调用子组件的方法或访问其属性。
父组件:
<template>
<ChildComponent ref="childRef" />
</template>
<script setup>
import { ref, onMounted } from 'vue';
import ChildComponent from './ChildComponent.vue';
const childRef = ref(null);
onMounted(() => {
if (childRef.value) {
childRef.value.someMethod(); // 假设子组件有一个someMethod方法
}
});
</script>
子组件:
<template>
<p>Hello from Child</p>
</template>
<script setup>
function someMethod() {
console.log('Called from Parent');
}
</script>
4. Vuex
与Pinia
对于大型应用,当组件间通信变得非常复杂时,可以考虑使用状态管理库如Vuex或Pinia。
Vuex:
// store/index.js
import { createStore } from 'vuex';
export default createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
increment({ commit }) {
commit('increment');
}
},
getters: {
doubleCount: state => state.count * 2
}
});
使用Vuex:
<template>
<div>
<p>Count: {{ count }}</p>
<p>Double Count: {{ doubleCount }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script setup>
import { computed } from 'vue';
import { useStore } from 'vuex';
const store = useStore();
const count = computed(() => store.state.count);
const doubleCount = computed(() => store.getters.doubleCount);
function increment() {
store.dispatch('increment');
}
</script>
Pinia:
// store/index.js
import { defineStore } from 'pinia';
export const useMainStore = defineStore('main', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++;
}
},
getters: {
doubleCount: (state) => state.count * 2
}
});
使用Pinia:
<template>
<div>
<p>Count: {{ count }}</p>
<p>Double Count: {{ doubleCount }}</p>
<button @click="increment">Increment</button>
</div>
</template>
<script setup>
import { computed } from 'vue';
import { useMainStore } from '@/store';
const store = useMainStore();
const count = computed(() => store.count);
const doubleCount = computed(() => store.doubleCount);
function increment() {
store.increment();
}
</script>
总结
选项式API:适用于熟悉Vue 2的开发者,代码结构清晰,适合中小型项目。
组合式API:提供了更灵活的代码组织方式,适合大型项目和复杂的业务逻辑。
无论是哪种API风格,Vue 3都提供了丰富的工具和方法来实现组件间的高效通信。选择合适的API风格和通信方式,可以显著提升开发效率和代码的可维护性。
标签:count,Vue,const,间通信,theme,API,组件,import From: https://blog.csdn.net/misstianyun/article/details/143994549