Reputation: 151
I'm new in vuejs 2. I have many component and I'm having problem in global event handling, here is my component structure -> Image . I'm using Dynamic-Component to handle my components. I have forms in component 1 and 2. If i submit the form, it will be saved in allData.js file, and will show there. So as i study and found that, to communicate with components i need to use global event handler(eventBus). Here is my code (only scripted part included):
in my main.js
, i included this:
import Vue from 'vue';
import App from './App.vue';
import allData from './components/allDataTemplate.vue';
Vue.prototype.$eventHub = new Vue();
//Other codes
by that $eventHub will be accessible from any component and i don't have to import to any other component.
In my App.js
, i included all my form components:
import componentOne from './components/componentOneTemplate';
import componentTwo from './components/componentTwoTemplate';
//Other codes
Im my componentOne/Two I'm emmiting event like this:
this.$eventHub.$emit('DataPassed', formData);
Now in allData.js
, file where i need to listen to this handler (probably the problematic part), i'm listening to that event, and destroying it when leaving it:
methods: {
whenCalled() {
console.log('fired');
}
},
created() {
this.$eventHub.$on('DataPassed', this.whenCalled);
},
beforeDestroy() {
this.$eventHub.$off('DataPassed', this.whenCalled);
}
Problem No 1: Here event not listening if i destroyed the event. Problem No 2: But if i comment out destroy event i can listen the event, which bring another problem. It triggering many times(the count of time that i visit the tab). Can anyone help me how to solve this problem?
Upvotes: 1
Views: 1220
Reputation: 576
I think you should do
this.$eventHub.$on('DataPassed', this.whenCalled.bind(this));
or you can do
this.$eventHub.$on('DataPassed', () => { this.whenCalled });
I suspect this issue is related to the scope of the function 'whenCalled' in how you declare it in $on
Please check this link, i did a helper class which is injected as a VueHelper, the advantage is you can throw events inside the components and js files (no components) as well. I'm using this code and i am sure it works. https://kopy.io/ncytP
Updated kopy.io https://kopy.io/5u63D
Update: Since the kopy files has an expiration i will add the full code below
// Class EventEmitter
// events/index.js
import Vue from 'vue'
export class AppEventEmitter {
constructor () {
this.evt = new Vue()
}
listen (evt, callback) {
this.evt.$on(evt, callback)
}
fire (evt, data = null) {
this.evt.$emit(evt, data)
}
destroy (evt, callback) {
this.evt.$off(evt, callback)
}
}
export const AppEvent = new AppEventEmitter()
________________________________________________
// Main.js
import { AppEvent } from 'src/events'
Vue.prototype.$event = AppEvent
// Usage in vue components
this.$event.listen('ChartDataPassed', () => { this.whenCalled() })
this.$event.fire('ChartDataPassed', { value: 1, key: 'value' })
this.$event.destroy('ChartDataPassed', () => { this.whenCalled() });
// Usage in JS files
// It works even if you also throw the event in other js files by doing
AppEvent.fire('submission-process:photos-completed', { value: 1, key: 'value' })
Upvotes: 2
Reputation: 1964
You must write like following...
this.$eventHub.$on('DataPassed', function(payload) {
// Here you can do anything with your passed data as payload
});
ES6 Format,
this.$eventHub.$on('DataPassed', (payload) => {
// try something from here.
})
Upvotes: 1