In a Vue.js app, I have two sibling components: a map view and a status bar. The status bar shows, amongst other things, the current geographical coordinates of the mouse pointer.
Currently I have a mousemove
event handler in the MapView
component, which calculates the geographic coordinates of the pointer and commits them to the app's Vuex store. The StatusBar
component displays the values from the Vuex store.
The problems are twofold.
I am unsure if it's right to be committing to the Vuex store on
mousemove
. Themousemove
event can fire up to 60–100 times per second. Amongst other problems, this causes the Vue devtools plugin to freeze.The calculation of the geographic coordinates is not completely trivial. It would be better if it was done only when rendering the
StatusBar
, rather than every time themousemove
event handler runs. But to do that, I would need to be able to access methods of theMapView
component from theStatusBar
component, which I don't think is possible (or at least idiomatic) in Vue.
I can see a couple of other options, but I'm not sure of the merits of them:
I could use a global event bus, and the
mousemove
event handler in theMapView
component could fire an event which included a reference to theMapView
as an argument. Then theStatusBar
component would have access to theMapView
to call it's methods to calculate the geographic coordinates. This would avoid the extremely frequent commits to the Vuex store, but I don't know if it would be any more efficient really. Furthermore, I would still be effectively doing the geographic calculations onmousemove
, rather than on render.Perhaps I could store a reference to the
MapView
as a property of$root
, and thus be able to directly access it's methods from theStatusBar
component. This feels cludgy and I'm sure it's not an idiomatic thins to do in Vue.
Both of the above methods would also result in tight bindings between the StatusBar
and MapView
components, which is less than ideal.
- A third option would be to simply throttle my
mousemove
handler to run less often. But for the status bar to update smoothly it would still have to run 10 times a second or so, and I'm still uncertain if Vuex is the right place for data which changes that often.
What would be the idiomatic (and most performant) way to handle this in Vue? And is the Vuex store the right place for data which changes so frequently?