设计思路
- 使用Provide/Inject 实现跨组件通信:通过
provide
在父组件中提供数据或方法,子组件通过inject
来获取,适用于深度嵌套组件间通信。
- 使用自定义事件总线:创建一个独立的Vue实例作为事件总线,模块间通过事件总线来触发和监听事件,实现通信。
- 状态管理:利用Vuex来管理共享状态,各个模块都可以从Vuex中获取和修改状态,达到解耦通信目的。
关键代码实现
Provide/Inject
- 商品模块:
<template>
<div>
<button @click="addToCart(product)">添加到购物车</button>
</div>
</template>
<script setup>
import { provide } from 'vue';
import { ref } from 'vue';
const product = ref({ name: '示例商品', price: 10 });
const addToCart = (product) => {
// 这里逻辑可实际将商品添加到购物车逻辑
console.log(`将 ${product.name} 添加到购物车`);
};
provide('product', product);
provide('addToCart', addToCart);
</script>
- 购物车模块:
<template>
<div>
<div v-for="item in cartItems" :key="item.name">{{ item.name }} - {{ item.price }}</div>
</div>
</template>
<script setup>
import { inject } from 'vue';
const product = inject('product');
const addToCart = inject('addToCart');
const cartItems = [];
// 这里假设购物车添加逻辑
if (product.value && addToCart) {
cartItems.push(product.value);
}
</script>
- 订单模块:
<template>
<div>
<p>订单总价: {{ totalPrice }}</p>
</div>
</template>
<script setup>
import { inject } from 'vue';
const cartItems = inject('cartItems');
const totalPrice = computed(() => {
return cartItems.reduce((acc, item) => acc + item.price, 0);
});
</script>
自定义事件总线
- 创建事件总线:
import { createApp } from 'vue';
const eventBus = createApp({}).config.globalProperties.$eventBus = new Vue();
export default eventBus;
- 商品模块:
<template>
<div>
<button @click="addToCart(product)">添加到购物车</button>
</div>
</template>
<script setup>
import eventBus from './eventBus';
import { ref } from 'vue';
const product = ref({ name: '示例商品', price: 10 });
const addToCart = (product) => {
eventBus.$emit('productAdded', product);
console.log(`将 ${product.name} 添加到购物车`);
};
</script>
- 购物车模块:
<template>
<div>
<div v-for="item in cartItems" :key="item.name">{{ item.name }} - {{ item.price }}</div>
</div>
</template>
<script setup>
import eventBus from './eventBus';
import { ref } from 'vue';
const cartItems = ref([]);
eventBus.$on('productAdded', (product) => {
cartItems.value.push(product);
eventBus.$emit('cartUpdated', cartItems.value);
});
</script>
- 订单模块:
<template>
<div>
<p>订单总价: {{ totalPrice }}</p>
</div>
</template>
<script setup>
import eventBus from './eventBus';
import { ref, computed } from 'vue';
const cartItems = ref([]);
const totalPrice = computed(() => {
return cartItems.value.reduce((acc, item) => acc + item.price, 0);
});
eventBus.$on('cartUpdated', (items) => {
cartItems.value = items;
});
</script>
Vuex
- 安装并配置Vuex:
import { createStore } from 'vuex';
const store = createStore({
state() {
return {
cartItems: [],
};
},
mutations: {
addProductToCart(state, product) {
state.cartItems.push(product);
},
},
getters: {
totalPrice(state) {
return state.cartItems.reduce((acc, item) => acc + item.price, 0);
},
},
});
export default store;
- 商品模块:
<template>
<div>
<button @click="addToCart(product)">添加到购物车</button>
</div>
</template>
<script setup>
import { useStore } from 'vuex';
import { ref } from 'vue';
const product = ref({ name: '示例商品', price: 10 });
const store = useStore();
const addToCart = (product) => {
store.commit('addProductToCart', product);
console.log(`将 ${product.name} 添加到购物车`);
};
</script>
- 订单模块:
<template>
<div>
<p>订单总价: {{ totalPrice }}</p>
</div>
</template>
<script setup>
import { useStore } from 'vuex';
const store = useStore();
const totalPrice = computed(() => store.getters.totalPrice);
</script>