具有组合的 Vue 3 事件总线 API
Vue 3 Event Bus with Composition API
我已经设置 mitt 并尝试将事件分派给另一个组件,但我遇到了困难,因为在 setup()
方法中它没有 this
用于访问应用程序实例.
这是我尝试过的:
import App from './App.vue'
const el = document.getElementById('app')
import mitt from 'mitt';
const emitter = mitt();
const app = createApp(App)
app.config.globalProperties.emitter = emitter;
app.mount(el);
并且在组件中,我想调度一个事件
export default {
setup() {
function toggleSidebar() {
this.emitter.emit('toggle-sidebar');
console.log(this); // binds to setup(), not the vue instance.
}
}
}
由于 this
不存在,我无法访问 .emitter
。我错过了什么?如何在Vue 3组合中使用官方推荐的mitt api?
顺便说一下,如果我使用 v2 语法,我可以访问 this.emitter
。但是我很好奇 Composition API way
export default {
mounted() {
console.log(this.emitter); // works
}
}
您可以使用 getCurrentInstance
获取全局 属性
组件:
import { getCurrentInstance } from 'vue';
export default {
setup() {
// get current instance
const internalInstance = getCurrentInstance();
// get the emitter from the instance
const emitter = internalInstance.appContext.config.globalProperties.emitter;
}
}
要在 Vue 3 组合中使用事件总线 API,请在任何组件中使用 Vue 3 的新 provide
api in main.js, and then inject
:
1.安装 mitt:
npm install mitt
2。提供:
main.js
import { createApp } from 'vue';
import App from './App.vue';
import mitt from 'mitt'; // Import mitt
const emitter = mitt(); // Initialize mitt
const app = createApp(App);
app.provide('emitter', emitter); // ✅ Provide as `emitter`
app.mount('#app');
3。注入
3a。 任何组件 - 发出一个事件
import { inject } from 'vue'
export default {
setup() {
const emitter = inject('emitter'); // Inject `emitter`
const mymethod = () => {
emitter.emit('myevent', 100);
};
return {
mymethod
}
}
}
通过单击按钮或其他方式调用 mymethod
。
3b。 任何组件 - 监听 事件
import { inject } from 'vue'
export default {
setup() {
const emitter = inject('emitter'); // Inject `emitter`
emitter.on('myevent', (value) => { // *Listen* for event
console.log('myevent received!', `value: ${value}`);
});
},
}
控制台
myevent received! value: 100
到目前为止,我已经使用此代码使“发射器”可用。
//main.ts
import mitt from 'mitt'
const emitter = mitt()
export default emitter
然后在我使用的组件内部
import emitter from '@/main';
到目前为止,这在 Vue2 和 Vue3 中有效 - 至少在选项 API.
中
我不得不承认,我目前 运行 在使用新的 vite 服务器和热模块重新加载 (hmr) 时遇到了一些麻烦。
这种风格在任何方面都不是最理想的吗?
我已经设置 mitt 并尝试将事件分派给另一个组件,但我遇到了困难,因为在 setup()
方法中它没有 this
用于访问应用程序实例.
这是我尝试过的:
import App from './App.vue'
const el = document.getElementById('app')
import mitt from 'mitt';
const emitter = mitt();
const app = createApp(App)
app.config.globalProperties.emitter = emitter;
app.mount(el);
并且在组件中,我想调度一个事件
export default {
setup() {
function toggleSidebar() {
this.emitter.emit('toggle-sidebar');
console.log(this); // binds to setup(), not the vue instance.
}
}
}
由于 this
不存在,我无法访问 .emitter
。我错过了什么?如何在Vue 3组合中使用官方推荐的mitt api?
顺便说一下,如果我使用 v2 语法,我可以访问 this.emitter
。但是我很好奇 Composition API way
export default {
mounted() {
console.log(this.emitter); // works
}
}
您可以使用 getCurrentInstance
获取全局 属性
组件:
import { getCurrentInstance } from 'vue';
export default {
setup() {
// get current instance
const internalInstance = getCurrentInstance();
// get the emitter from the instance
const emitter = internalInstance.appContext.config.globalProperties.emitter;
}
}
要在 Vue 3 组合中使用事件总线 API,请在任何组件中使用 Vue 3 的新 provide
api in main.js, and then inject
:
1.安装 mitt:
npm install mitt
2。提供:
main.js
import { createApp } from 'vue';
import App from './App.vue';
import mitt from 'mitt'; // Import mitt
const emitter = mitt(); // Initialize mitt
const app = createApp(App);
app.provide('emitter', emitter); // ✅ Provide as `emitter`
app.mount('#app');
3。注入
3a。 任何组件 - 发出一个事件
import { inject } from 'vue'
export default {
setup() {
const emitter = inject('emitter'); // Inject `emitter`
const mymethod = () => {
emitter.emit('myevent', 100);
};
return {
mymethod
}
}
}
通过单击按钮或其他方式调用 mymethod
。
3b。 任何组件 - 监听 事件
import { inject } from 'vue'
export default {
setup() {
const emitter = inject('emitter'); // Inject `emitter`
emitter.on('myevent', (value) => { // *Listen* for event
console.log('myevent received!', `value: ${value}`);
});
},
}
控制台
myevent received! value: 100
到目前为止,我已经使用此代码使“发射器”可用。
//main.ts
import mitt from 'mitt'
const emitter = mitt()
export default emitter
然后在我使用的组件内部
import emitter from '@/main';
到目前为止,这在 Vue2 和 Vue3 中有效 - 至少在选项 API.
中我不得不承认,我目前 运行 在使用新的 vite 服务器和热模块重新加载 (hmr) 时遇到了一些麻烦。 这种风格在任何方面都不是最理想的吗?