在 Vue 3 中,eventBus 的概念已经被弱,不保举使用全局事件总线,
你需要一个轻量级的事件总线,可以自己封装一个 EventBus 类,也有一些替换方案
1、使用第三方库(如 mitt 或 tiny-emitter)
mitt 是一个轻量级的事件发射器,适合在 Vue 3 中替换事件总线。它不依赖 Vue 实例,体积小且易于使用。
- // src/utils/eventBus.js
- import mitt from 'mitt';
- export const emitter = mitt();
复制代码- import { emitter } from './utils/eventBus';
- // 触发事件
- emitter.emit('event-name', data);
- // 取消监听
- emitter.off('event-name', handler);
复制代码 2、依赖注入
provide 和 inject 是 Vue 3 保举的父子组件通信方式,适合在组件树中传递数据。
- // 父组件
- import { provide } from 'vue';
- export default {
- setup() {
- provide('message', 'Hello from Parent');
- }
- };
复制代码- // 子组件
- import { inject } from 'vue';
- export default {
- setup() {
- const message = inject('message');
- console.log(message);
- }
- };
复制代码 3、使用vuex或者pina
对于复杂的状态管理,保举使用 Vuex 或 Pinia。它们提供了更强大的状态管理能力,适合大型项目。
- // store.js
- import { createStore } from 'vuex';
- export default createStore({
- state: {
- message: 'Hello from Vuex'
- },
- mutations: {
- updateMessage(state, payload) {
- state.message = payload;
- }
- }
- });
复制代码- import { useStore } from 'vuex';
- export default {
- setup() {
- const store = useStore();
- store.commit('updateMessage', 'New Message');
- console.log(store.state.message);
- }
- };
复制代码 4、使用props和emits
对于父子组件通信,props 和 emits 是最直接的方式。
- <template>
- <ChildComponent :message="message" @update="handleUpdate" />
- </template>
- <script>
- import ChildComponent from './ChildComponent.vue';
- export default {
- components: {
- ChildComponent
- },
- data() {
- return {
- message: 'Hello from Parent'
- };
- },
- methods: {
- handleUpdate(newMessage) {
- this.message = newMessage;
- }
- }
- };
- </script>
复制代码- <template>
- <button @click="updateMessage">Update Message</button>
- </template>
- <script>
- export default {
- props: ['message'],
- emits: ['update'],
- methods: {
- updateMessage() {
- this.$emit('update', 'New Message');
- }
- }
- };
- </script>
复制代码 5、自己封装
在 Vue 3 中,你可以通过创建一个 Vue 实例作为事件总线来实现类似的功能。
- // src/eventBus.js
- import { createApp } from 'vue';
- const eventBus = createApp({});
- // 添加自定义事件方法
- eventBus.config.globalProperties.$emit = function (event, ...args) {
- this._eventBus.emit(event, ...args);
- };
- eventBus.config.globalProperties.$on = function (event, callback) {
- this._eventBus.on(event, callback);
- };
- eventBus.config.globalProperties.$off = function (event, callback) {
- this._eventBus.off(event, callback);
- };
- // 创建一个内部的事件总线
- eventBus._eventBus = {
- events: {},
-
- on(event, callback) {
- if (!this.events[event]) {
- this.events[event] = [];
- }
- this.events[event].push(callback);
- },
-
- emit(event, ...args) {
- if (this.events[event]) {
- this.events[event].forEach(callback => {
- callback(...args);
- });
- }
- },
-
- off(event, callback) {
- if (this.events[event]) {
- this.events[event] = this.events[event].filter(cb => cb !== callback);
- }
- }
- };
- export default eventBus;
复制代码 子组件
- // src/eventBus.js
- import { createApp } from 'vue';
- const eventBus = createApp({});
- // 添加自定义事件方法
- eventBus.config.globalProperties.$emit = function (event, ...args) {
- this._eventBus.emit(event, ...args);
- };
- eventBus.config.globalProperties.$on = function (event, callback) {
- this._eventBus.on(event, callback);
- };
- eventBus.config.globalProperties.$off = function (event, callback) {
- this._eventBus.off(event, callback);
- };
- // 创建一个内部的事件总线
- eventBus._eventBus = {
- events: {},
-
- on(event, callback) {
- if (!this.events[event]) {
- this.events[event] = [];
- }
- this.events[event].push(callback);
- },
-
- emit(event, ...args) {
- if (this.events[event]) {
- this.events[event].forEach(callback => {
- callback(...args);
- });
- }
- },
-
- off(event, callback) {
- if (this.events[event]) {
- this.events[event] = this.events[event].filter(cb => cb !== callback);
- }
- }
- };
- export default eventBus;
复制代码 父组件:
- <template>
- <ChildComponent />
- </template>
- <script>
- import ChildComponent from './ChildComponent.vue';
- import eventBus from '../eventBus';
- export default {
- components: {
- ChildComponent
- },
- created() {
- // 监听事件
- eventBus.$on('custom-event', this.handleCustomEvent);
- },
- beforeUnmount() {
- // 组件销毁时移除事件监听
- eventBus.$off('custom-event', this.handleCustomEvent);
- },
- methods: {
- handleCustomEvent(message) {
- console.log('Event received:', message);
- // 在这里处理逻辑
- }
- }
- }
- </script>
复制代码 使用类方法封装一个事件总线
- // src/utils/EventBus.js
- class EventBus {
- constructor() {
- this.events = {};
- }
- /**
- * 监听事件
- * @param {string} event - 事件名称
- * @param {Function} callback - 回调函数
- */
- $on(event, callback) {
- if (!this.events[event]) {
- this.events[event] = [];
- }
- this.events[event].push(callback);
- }
- /**
- * 触发事件
- * @param {string} event - 事件名称
- * @param {...any} args - 传递给回调函数的参数
- */
- $emit(event, ...args) {
- if (this.events[event]) {
- this.events[event].forEach(callback => {
- callback(...args);
- });
- }
- }
- /**
- * 移除事件监听
- * @param {string} event - 事件名称
- * @param {Function} callback - 回调函数
- */
- $off(event, callback) {
- if (this.events[event]) {
- this.events[event] = this.events[event].filter(cb => cb !== callback);
- }
- }
- /**
- * 一次性监听事件
- * @param {string} event - 事件名称
- * @param {Function} callback - 回调函数
- */
- $once(event, callback) {
- const onceCallback = (...args) => {
- callback(...args);
- this.$off(event, onceCallback);
- };
- this.$on(event, onceCallback);
- }
- }
- // 创建一个 EventBus 实例
- const eventBus = new EventBus();
- export default eventBus;
复制代码 子组件
- <template>
- <button @click="handleClick">点击我</button>
- </template>
- <script>
- import eventBus from '../utils/EventBus';
- export default {
- methods: {
- handleClick() {
- // 触发事件
- eventBus.$emit('custom-event', 'Hello from Child');
- }
- }
- }
- </script>
复制代码 父组件
- <template>
- <ChildComponent />
- </template>
- <script>
- import ChildComponent from './ChildComponent.vue';
- import eventBus from '../utils/EventBus';
- export default {
- components: {
- ChildComponent
- },
- created() {
- // 监听事件
- eventBus.$on('custom-event', this.handleCustomEvent);
- },
- beforeUnmount() {
- // 组件销毁时移除事件监听
- eventBus.$off('custom-event', this.handleCustomEvent);
- },
- methods: {
- handleCustomEvent(message) {
- console.log('Event received:', message);
- // 在这里处理逻辑
- }
- }
- }
- </script>
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |