一般的话,主要使用这6种:
事件总线/Event Emitter模式(Vue2/3)
Vuex状态管理(Vue2)
Pinia状态管理(Vue3)
Provide/Inject依赖注入(Vue2/3)
组合式函数(Composables)(vue3)
下面将简单介绍及使用:
1. 事件总线/Event Emitter模式
事件总线是一种发布/订阅模式,允许组件之间进行通信。
Vue2 实现
// event-bus.js
import Vue from 'vue';
export const EventBus = new Vue();
// ComponentA.vue (发送事件)
<script>
import { EventBus } from './event-bus';
export default {
methods: {
sendMessage() {
EventBus.$emit('message-sent', this.message);
}
}
};
</script>
// ComponentB.vue (接收事件)
<script>
import { EventBus } from './event-bus';
export default {
created() {
EventBus.$on('message-sent', this.handleMessage);
},
beforeDestroy() {
EventBus.$off('message-sent', this.handleMessage);
},
methods: {
handleMessage(message) {
console.log(message);
}
}
};
</script>
Vue3 实现
由于Vue3不再有实例事件机制,需要自己实现一个事件总线,或者使用npm下包,比如mitt等等,详细见这里:如需了解请点此处
// event-bus.js
export const EventBus = {
events: {},
$on(event, callback) {
if (!this.events[event]) this.events[event] = [];
this.events[event].push(callback);
},
$emit(event, data) {
if (this.events[event]) {
this.events[event].forEach(callback => callback(data));
}
},
$off(event, callback) {
if (!this.events[event]) return;
if (!callback) {
delete this.events[event];
} else {
this.events[event] = this.events[event].filter(cb => cb !== callback);
}
}
};
/使用方式与Vue2类似,只是不需要导入Vue,而是导入这个自定义的EventBus
属性
$on(event, callback): 监听事件,当事件被触发时执行回调。
$emit(event, data): 触发事件,可传递数据。
$off(event, callback): 移除事件监听器。
注意事项
事件总线是全局的,容易导致事件冲突,建议给事件名加上命名空间。
在组件销毁前务必移除事件监听,避免内存泄漏。
不适合大型复杂项目,因为事件流会变得难以追踪。
2. Vuex状态管理(Vue2)
使用方法
Vuex是Vue官方状态管理库,适用于中大型项目。
安装与配置
npm install vuex
// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment');
}, 1000);
}
},
getters: {
doubleCount: state => state.count * 2
}
});
// main.js
import store from './store';
new Vue({
store,
// ...其他配置
}).$mount('#app');
在组件中使用
// Component.vue
<script>
export default {
computed: {
count() {
return this.$store.state.count;
},
doubleCount() {
return this.$store.getters.doubleCount;
}
},
methods: {
increment() {
this.$store.commit('increment');
},
incrementAsync() {
this.$store.dispatch('incrementAsync');
}
}
};
</script>
5个核心属性:
state: 存储应用状态的数据对象。
mutations: 更改state的唯一方法,必须是同步函数。
actions: 提交mutation,可以包含异步操作。
getters: 基于state的计算属性。
注意事项
不要直接修改state,必须通过commit mutation来修改。
使用mapState、mapGetters、mapMutations、mapActions辅助函数来简化代码。
模块化:当状态多的时候,可以将store分割成模块。
3. Pinia状态管理(Vue3)
使用方法
Pinia是Vue3推荐的状态管理库,比Vuex更简洁。
安装与配置
npm install pinia
// stores/counter.js
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++;
},
async incrementAsync() {
setTimeout(() => {
this.increment();
}, 1000);
}
},
getters: {
doubleCount: (state) => state.count * 2
}
});
// main.js
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';
const pinia = createPinia();
createApp(App).use(pinia).mount('#app');
在组件中使用
<script>
import { useCounterStore } from '@/stores/counter';
export default {
setup() {
const counterStore = useCounterStore();
return {
count: counterStore.count,
doubleCount: counterStore.doubleCount,
increment: counterStore.increment,
incrementAsync: counterStore.incrementAsync
};
}
};
</script>
3个核心属性
state: 存储状态。
actions: 可以是同步或异步,直接修改state。
getters: 计算属性。
注意事项
Pinia没有mutations,actions直接修改state。
支持TypeScript,提供更好的类型推断。
支持模块化,每个store都是一个独立的模块。
4. Provide/Inject依赖注入
使用方法
祖先组件提供数据,后代组件注入数据。
Vue2 实现
// 祖先组件
<script>
export default {
provide() {
return {
message: this.message
};
},
data() {
return {
message: 'Hello from ancestor'
};
}
};
</script>
// 后代组件
<script>
export default {
inject: ['message']
};
</script>
Vue3 实现
// 祖先组件
<script>
import { provide, ref } from 'vue';
export default {
setup() {
const message = ref('Hello from ancestor');
provide('message', message);
return { message };
}
};
</script>
// 后代组件
<script>
import { inject } from 'vue';
export default {
setup() {
const message = inject('message');
return { message };
}
};
</script>
注意
提供的数据不是响应式的(Vue2中),如果需要响应式,可以提供父组件的实例或使用observable。
在Vue3中,使用ref或reactive提供响应式数据。
主要用于开发高阶插件/组件库,普通应用慎用,因为会导致组件间耦合。
5. 组合式函数(Composables)
使用方法
组合式函数是Vue3的特性,用于封装可复用的逻辑。
示例
javascript
// useCounter.js
import { ref, computed } from 'vue';
export function useCounter() {
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
function increment() {
count.value++;
}
return { count, doubleCount, increment };
}
// 在组件中使用
<script>
import { useCounter } from './useCounter';
export default {
setup() {
const { count, doubleCount, increment } = useCounter();
return { count, doubleCount, increment };
}
};
</script>
注意事项
组合式函数命名通常以use开头。
可以在组合式函数内部使用其他组合式函数,实现逻辑组合。
适合提取可复用的逻辑,使组件更简洁。
最后:
事件总线:简单场景,非父子组件通信,但容易导致混乱。
Vuex:Vue2中大型项目状态管理。
Pinia:Vue3推荐的状态管理,API更简洁。
Provide/Inject:深层嵌套组件通信,但耦合性高。
组合式函数:Vue3逻辑复用,提高代码可维护性。
Vue2/Vue3多组件通信方案
1033

被折叠的 条评论
为什么被折叠?



