如何在一个页面上使用事件总线,以便所有组件和页面都可以读取和接收那里的事件例如,在 vue 2 中,我创建了一个对象,该对象在创建页面时分配了上下文的字段,并且我使用了页面所有组件中的此上下文示例
//main.js
global.context = new Object();
global.context.app = Vue;
//field assignment with context
global.context.authorization = this;
//using context
global.context.authorization.$emit(
"authorizationMessage",
this.t("Password fields didn't match")
);
Run Code Online (Sandbox Code Playgroud)
我可以使用导入来改进这种方法吗?在 vue 3 中,我使用时遇到错误
global.context.authorization.$on("authorizationMessage", (msg) => {
alert(msg);
});
Run Code Online (Sandbox Code Playgroud)
Uncaught (in promise) TypeError: global.context.authorization.$on is not a function
at Proxy.created (Messenger.vue?1b1a:25)
at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:154)
at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?5c40:163)
at callHookWithMixinAndExtends (runtime-core.esm-bundler.js?5c40:6032)
at callSyncHook (runtime-core.esm-bundler.js?5c40:6018)
at applyOptions (runtime-core.esm-bundler.js?5c40:5956)
at finishComponentSetup (runtime-core.esm-bundler.js?5c40:6636)
at setupStatefulComponent (runtime-core.esm-bundler.js?5c40:6567)
at setupComponent (runtime-core.esm-bundler.js?5c40:6503)
at mountComponent (runtime-core.esm-bundler.js?5c40:4206)
Run Code Online (Sandbox Code Playgroud)
Ndi*_*asi 12
Vue 3 中没有事件总线。所以$on不起作用。请参阅:https ://v3-migration.vuejs.org/writing-changes/events-api.html#events-api
建议您使用外部库创建事件总线,除非您想利用受支持的父子基于事件的通信,其中子级发出只能由父级监听的事件。请参阅:https://v3.vuejs.org/guide/component-custom-events.html#custom-events
要为您的应用程序实现事件总线,请确保您正在发出(激发)事件并使用同一发射器实例侦听它们。不然就不行了
我更喜欢emittery(https://github.com/sindresorhus/emittery)使用 Vue js 的事件总线。它非常强大,具有出色的 Typescript 支持。我还通过 Adonisjs 框架在 Node js 上使用它。
创建一个 useEvent 挂钩 //文件:composables/useEvent.ts
import Emittery from 'emittery';
const emitter = new Emittery();
// Export the Emittery class and its instance.
// The `emitter` instance is more important for us here
export {emitter, Emittery};
Run Code Online (Sandbox Code Playgroud)
// 导出 Emittery 类及其实例 export {emitter, Emittery };
<script lang="ts">
import { defineComponent, onMounted } from 'vue';
import {emitter} from '../composables/useEvent'
export default defineComponent({
name: 'ExampleComponent',
components: {},
props: {},
setup() {
onMounted(() => {
emitter.on('event-name', async () => {
// Perform actions. async...await is supported
});
})
return {};
},
});
</script>
Run Code Online (Sandbox Code Playgroud)
<script lang="ts">
import { defineComponent, onMounted } from 'vue';
import {emitter} from '../composables/useEvent'
export default defineComponent({
name: 'ExampleComponent',
components: {},
props: {},
setup() {
void emitter.emit('event-name');
return {};
},
});
</script>
Run Code Online (Sandbox Code Playgroud)
useEvent钩子导入到任何非 Vue 文件中,它就会起作用。它只是一个 JS/TS 文件。对于 Quasar 框架:
import Emittery from 'emittery';
const emitter = new Emittery();
// Export the Emittery class and its instance.
// The `emitter` instance is more important for us here
export {emitter, Emittery};
Run Code Online (Sandbox Code Playgroud)
import { boot } from 'quasar/wrappers';
import Emittery from 'emittery';
const emitter = new Emittery();
export default boot(({ app }) => {
app.config.globalProperties.$event = emitter;
});
// Export the Emittery class and its instance
export { emitter, Emittery };
Run Code Online (Sandbox Code Playgroud)
quasar.conf.js用文件注册<script lang="ts">
import { defineComponent, onMounted } from 'vue';
import {emitter} from '../composables/useEvent'
export default defineComponent({
name: 'ExampleComponent',
components: {},
props: {},
setup() {
onMounted(() => {
emitter.on('event-name', async () => {
// Perform actions. async...await is supported
});
})
return {};
},
});
</script>
Run Code Online (Sandbox Code Playgroud)
<script lang="ts">
import { defineComponent, onMounted } from 'vue';
import {emitter} from '../boot/EventBus'
export default defineComponent({
name: 'ExampleComponent',
components: {},
props: {},
setup() {
onMounted(() => {
emitter.on('event-name', async () => {
// Perform actions. async...await is supported
});
})
return {};
},
});
</script>
Run Code Online (Sandbox Code Playgroud)
<script lang="ts">
import { defineComponent, onMounted } from 'vue';
import {emitter} from '../boot/EventBus'
export default defineComponent({
name: 'ExampleComponent',
components: {},
props: {},
setup() {
void emitter.emit('event-name');
return {};
},
});
</script>
Run Code Online (Sandbox Code Playgroud)
按照用作Vue事件总线的Vue 3 迁移指南,将该总线替换为以下实例tiny-emitter:
// event-bus.js
import emitter from 'tiny-emitter/instance'
export default {
$on: (...args) => emitter.on(...args),
$once: (...args) => emitter.once(...args),
$off: (...args) => emitter.off(...args),
$emit: (...args) => emitter.emit(...args),
}
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
// main.js
import eventBus from './event-bus'
//...
global.context.authorization = eventBus
Run Code Online (Sandbox Code Playgroud)