import { Vue } from 'vue-property-decorator'; function broadcast( this: any, componentName: string, eventName: string, params: any ) { this.$children.forEach((child: any) => { const name = child.$options.componentName; if (name === componentName) { child.$emit.apply(child, [...[eventName].concat(params)]); } else { broadcast.apply(child, [componentName, eventName, params]); } }); } export default class Emitter extends Vue { dispatch(componentName: string, eventName: string, params: any) { let parent: any = this.$parent || this.$root; let name = parent.$options.componentName; while (parent && (!name || name !== componentName)) { parent = parent.$parent; if (parent) { name = parent.$options.componentName; } } if (parent) { parent.$emit.apply(parent, [...[eventName].concat(params)]); } } broadcast(componentName: string, eventName: string, params: any) { broadcast.call(this, componentName, eventName, params); } }