在Vue3的世界里,组件之间的通信就像是社区中的居民交流信息。有的信息只需要邻居间悄悄传递,有的则需要整个社区都知道。Vue3提供了多种方式来实现这种交流,让我们用生活中的例子来解释这些通信方式,并附上Vue3的简单代码示例。
1. Props & Emits(父子通信)
理解:
想象一下,你在家里做了一些美味的蛋糕,想要分享给你的父母。你把蛋糕放在盘子里,通过传递盘子(props)来让你的父母品尝。这就是父子组件之间的通信方式。
- 父亲(父组件):"儿子,你做的蛋糕真好吃!"
- 儿子(子组件):通过传递蛋糕(props)来回应。
代码示例:
<!-- 父组件 -->
<template>
<!-- ... -->
<ChildComponent :cake="myCake" @requestCake="shareCake" />
<!-- ... -->
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const myCake = ref('巧克力蛋糕');
// 省略其他逻辑...
function shareCake(flavor) {
myCake.value = flavor;
}
</script>
<!-- 子组件 -->
<template>
<button @click="requestCake">请求草莓蛋糕</button>
<p>{{ cake }}</p>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps(['cake']);
const emit = defineEmits(['requestCake']);
// 省略其他逻辑...
function requestCake() {
emit('requestCake', '草莓蛋糕'); // 触发父组件的事件
}
</script>
Vue3 vs Vue2 对比:
- Vue3中引入了defineProps和defineEmits宏来声明props和emits,这使得在组合式API中使用更加简洁。
- Vue2中通常在组件选项中定义props,如props: ['cake'],而Vue3的组合式API提供了更现代化的语法。
2. Provide & Inject(祖先-后代通信)
理解:
假设你是一个家族的长辈,你有一个秘密配方想要传给你的孙子孙女。你可以通过口头传授(provide)这个秘密给他们,而他们可以随时使用(inject)这个秘密来制作美食。
- 祖父(祖先组件):"孩子们,这是我珍藏的烤鸭秘方。"
- 孙子(后代组件):通过注入(inject)来获取秘方并制作烤鸭。
代码示例:
<!-- 祖先组件 -->
<template>
<GrandchildComponent />
</template>
<script setup>
import { provide } from 'vue';
import GrandchildComponent from './GrandchildComponent.vue';
provide('secretRecipe', '家族烤鸭秘方');
// 省略其他逻辑...
</script>
<!-- 后代组件 -->
<template>
<div>{{ secretRecipe }}</div>
</template>
<script setup>
import { inject } from 'vue';
const secretRecipe = inject('secretRecipe');
// 省略其他逻辑...
</script>
Vue3 vs Vue2 对比:
- Vue3中provide和inject的使用变得更加直观,可以直接在组合式API的setup函数中使用。
- Vue2中需要分别在data和后代组件的created生命周期钩子中使用this.$parent.provide()和this.$parent.inject()。
3. Vuex(全局状态管理)
理解:
如果你是一个社区的管理员,你需要确保所有的居民都能及时得到重要信息,比如停电通知。你可以通过社区广播(Vuex)来实现这一点。
- 社区管理员(Vuex store):"各位居民,今晚9点将会有停电维护。"
- 居民(任何组件):通过收听广播(访问store)来获取信息。
代码示例:
javascript:
// Vuex store
import { createStore } from 'vuex';
export default createStore({
state: {
message: '今晚9点将会有停电维护'
},
mutations: {
updateMessage(state, newMessage) {
state.message = newMessage;
}
}
});
vue:
<!-- 任何组件 -->
<template>
<p>{{ $store.state.message }}</p>
</template>
<script setup>
import { onMounted } from 'vue';
onMounted(() => {
$store.commit('updateMessage', '新的通知:停电时间改为10点');
// 省略其他逻辑...
});
</script>
Vue3 vs Vue2 对比:
- Vue3中的Vuex仍然是全局状态管理的首选,但Vue3的组合式API使得局部状态管理变得更加容易,有时候可以减少对Vuex的依赖。
- Vue2和Vue3中Vuex的核心概念和用法基本相同,但在Vue3中,由于组合式API的引入,状态管理的代码组织方式可能会有所不同。
4. Reactive Variables(自定义响应式变量)
理解:
有时候,你只想在几个特定的朋友之间分享一些私密的事情,而不是整个社区。这时,你可以创建一个只有你们知道的秘密语言(reactive variables)。
- 好友A(组件A):"嘿,我有一个小秘密告诉你。"
- 好友B(组件B):通过共享的秘密语言(reactive variables)来理解秘密。
代码示例:
javascript:
// sharedVariables.js
import { reactive } from 'vue';
export const sharedSecret = reactive({
message: '这是一个秘密',
});
vue:
<!-- 组件A -->
<template>
<button @click="updateSecret">更新秘密</button>
</template>
<script setup>
import { sharedSecret } from './sharedVariables.js';
function updateSecret() {
sharedSecret.message = '新的秘密';
// 省略其他逻辑...
}
</script>
<!-- 组件B -->
<template>
<div>{{ sharedSecret.message }}</div>
</template>
<script setup>
import { sharedSecret } from './sharedVariables.js';
// 省略其他逻辑...
</script>
Vue3 vs Vue2 对比:
- Vue3的组合式API允许开发者更自由地创建和管理响应式数据,不再局限于组件实例内部。
- Vue2中的响应式数据通常绑定在组件实例的data选项中,而Vue3的响应式系统更加灵活,可以在组件之外创建响应式变量。