当前位置: 首页 > article >正文

vue3中事件总线

在 Vue 3 中,eventBus 的概念已经被弱,不推荐使用全局事件总线

你需要一个轻量级的事件总线,可以自己封装一个 EventBus 类,也有一些替代方案

1、使用第三方库(如 mitt 或 tiny-emitter)

mitt 是一个轻量级的事件发射器,适合在 Vue 3 中替代事件总线。它不依赖 Vue 实例,体积小且易于使用。

npm install mitt
// 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>

http://www.kler.cn/a/581861.html

相关文章:

  • 蓝桥杯备考:背包初次了解以及01背包
  • STM32-SPI通信外设
  • 搭建大数据技能竞赛比赛环境容器docker模块A-容器绑定物理网卡
  • HTML 属性(详细易懂)
  • ES的预置分词器
  • Linux IPC:System V共享内存汇总整理
  • 理解 XSS 和 CSP:保护你的 Web 应用免受恶意脚本攻击
  • 多光谱相机数据采集过程中常见仪器
  • <rust><tauri><GUI>基于tauri,打开任意windows电脑应用程序
  • 如何手动下载spring jar包
  • Vue.js 全面解析:构建现代前端应用的渐进式框架
  • SPA应用优化首屏加载速度
  • C++20 新特性总结
  • AWS原生架构下的服务器性能与成本平衡之道——海外业务云端实践
  • 用Python实现链上数据爬取与分析
  • RISC-V特权模式与寄存器
  • MATLAB 控制系统设计与仿真 - 22
  • 从零开始用AI开发游戏(一)
  • 关于在electron(Nodejs)中使用 Napi 的简单记录
  • 【GPT入门】第6课 openai接口介绍与参数说明