in my Nuxt app I have a Canvas that listens for mouse events. Now I want to send those mouse events to the DOM, everything is working fine. But I'm concerned that there are too many events for Vue, because there is like thousands of them. When I switch to the Vue dev tools, my Computer already begins to stutter. I feel like Vue is only made for simple click events, but I'm using it for a ton. Is there a better way to handle that?
init(){
document.addEventListener("mousemove", this.mouseMove.bind(this));
}
mouseMove(e){
EventBus.$emit("MOUSEMOVE", e);
}
It's okay if you need to add certain event listeners here and there. Just make sure you remove them when to component is destroyed, e.g.
mounted() {
window.addEventListener('eventName', yourMethod);
},
beforeDestroy() {
window.removeEventListener('eventName', yourMethod);
}
How about using debouncer for a short time limit.
I'm guessing that your DOM is not updating on every event and it takes some to self update. So slow down the event bus emit like in every 50/100 ms there will be an event fire. You can emit to event bus on every 50 MiliSecond or as per as your need. That would be helpful even if you solve the problem in other way.
Related
I want to know the concept of the below thing-
I have created one component and set up its respected event listeners. Now, I want to remove those listeners on this component's beforeDestroy hook before redirecting to another route that will create another component.
but what I noticed is, beforeDestory hook of the first component is calling even after the second component's created hook.
I want to destroy the first component completely and then create another component.
// To set up the event listeners
created() {
this.EventBus.$on('myCustomEvent', payload => {
// some code here
)}
}
// To destroy the event listeners
beforeDestroy() {
this.EventBus.$off('myCustomEvent');
}
Any suggestions?
In search of an answer to your question, I came to the conclusion that it is better to refuse to use EventBus altogether.
Here is some information on this and some thoughts from there:
I have that feeling that having an EventBus in Vue is an anti-pattern, especially if you’re using VueX but I can’t quite put my finger on it. At the point you want to be sharing data like that, wouldn’t it be better to use a store to handle all of those “events” / “mutations”?
Also, looking at the solution to this issue, you are doing everything right and there is no other way.
I have a custom Vue component that does not render to HTML.
When the component is first mounted, I am able to loop through this.$listeners and optimize the underlying non-HTML event implementation accordingly (e.g. not to emit mousemove type events unless something is listening).
To complete this process I'd like to know when listeners are programatically added later through $on().
Is there any non-polling way to be notified of this? My current workaround is to listen for and emit everything but that is a poor solution.
Note that in some instances I want to be able to use the events in question, and others not. For example:
<custom-component #eventThatWouldFireOften="doSomething" #anotherEvent="doMoreStuff"/>
and another usage might be simply.
<custom-component ref="custom"/>
...
mounted() {
this.$refs.custom.$on('anotherEvent', ...)
}
So in the first case the result would be:
CustomComponent tells the underlying API it wants to listen for eventThatWouldFireOften and anotherEvent
CustomComponent receives eventThatWouldFireOften and anotherEvent events from the underlying API and re-emits them as Vue events that can be listened to using v-on or # syntax.
..and the second case the result would be:
CustomComponent tells underlying API it doesn't want to listen for anything just yet
When the parent of CustomComponent is mounted it programatically listens for anotherEvent. That needs to be communicated down to the base API (what I'm trying to solve).
I have a Vue component that contains a Leaflet map. For the time being I'm using the event bus pattern to run some Leaflet methods when other components request it:
// in Map.vue
eventBus.$on('invalidateMapSize', () => {
this.map.invalidateSize(true)
})
eventBus.$on('setMapView', (coordinates, zoom) => {
this.map.setView(coordinates, zoom)
})
// in other components
eventBus.$emit('setMapView', [47.6623, 23.6970], 15)
Now I want to transition my app to Vuex and my question is how to achieve the same functionality?
While it is true that there is a trend on using VueX and steering away from the event bus pattern, I personally find both patterns to be complementary.
VueX states match well with Vue component data/props and their derivatives (computed, watch).
But there are cases where you do not manage a state, but really some event: a user click that should trigger a one time action (and you do not care about recording such a change, so a state is useless / overkill for this purpose); a network response that carries temporary data (like a search result); etc.
For these cases, I still use an event bus, since the equivalent feature has been purposefully removed from VueX.
In your situation, it seems to me that it fits well in the latter case: Leaflet does not (only) display static data derived from some states (could be the case of Markers, Tile Layers...), but enables user interactivity where your app can interfere by forcing a view from time to time, based on some events.
Trying to achieve this functionality using states would very probably require recording the last requested map view in a state, watching that state, and triggering a side effect on state change. Then there is an issue when it is requested to re-set the view to the same position...
Can anyone please let me know how to suspend/resume the events of a particular component. For example
textfieldObj.suspendEvents();
This will suspend all the events of that particular component means which will not fire any event listener if action happens also.
textfieldObj.resumeEvents();
All the events of that component will be fired if action performs.
Is there any thing like this in titanium?
Thanks in Advance,
Swathi.
In Titanium you can add and remove eventListeners. This goes for all Titanium types which are capable of firing events.
If you want to receive all events of a type (e.g. click) use
textfieldObj.addEventListener('click', function(e){
// perform your action
});
If you don't want to receive anymore events use
textfieldObj.removeEventListener('click', function(e){
// perform your action
});
You can read about it in the documentation.
If that doesnt work, this is Javascript and you can apply Backbone Events to the objects - http://backbonejs.org/#Events
I want to add listeners on selection event, but implementation via code below fired event two times. Only javascript core onClick event is fired correctly one time.
dojo.connect(myTabCont, "onButtonClicked", function(tabList){
console.log(tablist);
});
dojo.connect(myTabCont, "selectChild", function(tabList){
console.log(tablist);
});
//work fine - one click one fire
dojo.connect(myTabCont, "onClick", function(event){
console.log(event);
});
Is there is feature or bug? Or can you help how to workaround these funcionality or way how to broke this feature || bug.
Thanks
Sounds like a bug. selectChild() is idempotent so there's no harm in calling it twice (except for people like you that are connecting to it :-) ), so that's why we didn't notice the problem.
You could monitor the [widgetId]-selectChild topic, which will only fire once, or just ignore myTC.selectChild(foo) calls when foo == myTC.selectedChildWidget.
You could monitor the
[widgetId]-selectChild topic, which
will only fire once, or just ignore
myTC.selectChild(foo) calls when foo
== myTC.selectedChildWidget.
Equals check between old-selection and new-selection in Stack_Container.selectChild method is ok!
There is no bug. Registered "selectChild" is called two times and this is correct behaviour. First calling of "selectChild" is event fired by user, the second calling is programmaticlly when StackContainer check if old-selection NOT equals new-selection and fire onclick on tabItem explicitly.