在组件中使用组件时,有没有办法让事件冒泡?
Is there a way to allow events to bubble up when using a component within a component?
我的应用程序是一个动态菜单.动态菜单是一个组件 (dyn-menu),它为每个 <li>menu-item)> 元素.每个 <menu-item> 都有一个与之关联的单击处理程序,该处理程序发出一个自定义事件(在完整实现中具有菜单项的 ID).但是应用程序看不到 <menu-item> 发出的事件,因为它们没有冒泡.
My application is a dynamic menu. The dynamic menu is a component (dyn-menu) and it uses a local component (menu-item) for each of the <li> elements. Each <menu-item> has a click handler associated with it that emits a custom event (with an ID for menu item in the full implementation). But the application doesn't see the events issued by <menu-item> because they are not bubbled up.
有没有办法允许 组件本地的 <menu-item> 组件发出事件并且仍然允许 vapp 查看和处理事件吗?
Is there a way to allow the <menu-item> component, which is local to the <dyn-menu> component, emit the event and still allow vapp to see and handle the event?
我对 Vuejs 很陌生,所以我可能会遗漏一些明显的东西.我可能试图通过使用两个组件来解决这个问题,但这不是处理它的最佳方法.有没有更好的方法来解决它?
I'm pretty new to Vuejs so I might be missing something obvious. And it's possible that I'm trying to solve this by using two components and that's not the best way to handle it. Is there is a better way to approach it?
这是一个 jsfiddle.您必须删除 <dyn-menu> 模板中的 @dyn-menu-item-click='itemClick' 行以说明事件不会冒泡如果组件不处理事件,则向上.如果删除该行,则 <dyn-menu> 不会处理该事件,但 vapp 也不会看到该事件.
Here's a jsfiddle. You have to remove the @dyn-menu-item-click='itemClick' line in the <dyn-menu> template to illustrate that the event doesn't bubble up if the component doesn't handle the event. If that line is removed then <dyn-menu> doesn't handle the event but vapp never sees the event either.
我知道有 4 个选项
this.$parent 来访问所需的父组件并发出事件.(请参阅下面的实现您自己的冒泡事件插件")提供并在子级中注入的事件总线.this.$parent (repetitively) on the child component to access the desired parent and emit the event. (see "Implement your own bubbling event plugin" below)provided by the parent and injected in the children.这很简单.该插件添加了一个新的 $bubble 方法,该方法向其父级发出冒泡事件.我考虑过发布一个插件来做到这一点,但它是如此简单,以至于开销不值得.
It's very simple. The plugin adds a new $bubble method that emits events that bubble to their parents. I considered publishing a plugin that does this, but it's so simple that the overhead is not worth it.
// Add this as a Vue plugin
Vue.use((Vue) => {
Vue.prototype.$bubble = function $bubble(eventName, ...args) {
// Emit the event on all parent components
let component = this;
do {
component.$emit(eventName, ...args);
component = component.$parent;
} while (component);
};
});
// Some nested components as an example
// note usage of "$bubble" instead of "$emit"
Vue.component('component-c', {
template: `
<button type="button" @click="$bubble('my-event', 'payload')">
Emit bubbling event
</button>`,
});
Vue.component('component-b', {
template: `<component-c @my-event="onMyEvent" />`,
methods: {
onMyEvent(...args) {
console.log('component-b listener: ', ...args);
},
},
});
Vue.component('component-a', {
template: `<component-b @my-event="onMyEvent" />`,
methods: {
onMyEvent(...args) {
console.log('component-a listener: ', ...args);
},
},
});
var vapp = new Vue({
el: '#app',
methods: {
onMyEvent(...args) {
console.log('root listener: ', ...args);
},
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<component-a @my-event="onMyEvent" />
</div>
事件总线如下所示:
Vue.component('dyn-menu', {
components: {
'menu-item': {
template: '<li @click="itemClick">{{item.text}}</li>',
props: ['item'],
inject: ['eventBus'], // <-- Inject in the child
methods: {
itemClick() {
// Emit the event on the event bus
this.eventBus.$emit('dyn-menu-item-click', ['menu-item dyn-menu-item-click']);
}
}
}
},
// ...
});
var vapp = new Vue({
el: '#app',
data: {
// ...
eventBus: new Vue(),
},
provide() {
return {
// The parent component provides the event bus to its children
eventBus: this.eventBus,
};
},
created() {
// Listen to events on the event bus
this.eventBus.$on('dyn-menu-item-click', this.menuClick);
},
methods: {
menuClick(message) {}
}
})
工作示例:https://jsfiddle.net/7vwfx52b/
这里列出了很多事件总线插件:https://github.com/vuejs/awesome-vue#custom-events
There are plenty of event bus plugins listed here: https://github.com/vuejs/awesome-vue#custom-events
这篇关于Vuejs - 冒泡自定义事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
在 Angular 2/Typescript 中使用 IScrollUse IScroll in Angular 2 / Typescript(在 Angular 2/Typescript 中使用 IScroll)
Anime.js 在 Ionic 3 项目中不起作用anime.js not working in Ionic 3 project(Anime.js 在 Ionic 3 项目中不起作用)
Ionic 3 - 使用异步数据更新 ObservableIonic 3 - Update Observable with Asynchronous Data(Ionic 3 - 使用异步数据更新 Observable)
Angular 2:在本地 .json 文件中找不到文件Angular 2: file not found on local .json file(Angular 2:在本地 .json 文件中找不到文件)
在 Ionic 2 中,如何创建使用 Ionic 组件的自定义指In Ionic 2, how do I create a custom directive that uses Ionic components?(在 Ionic 2 中,如何创建使用 Ionic 组件的自定义指令?)
将 ViewChild 用于动态元素 - Angular 2 &离子2Use ViewChild for dynamic elements - Angular 2 amp; ionic 2(将 ViewChild 用于动态元素 - Angular 2 amp;离子2)