Skip to content

Instantly share code, notes, and snippets.

@DaniJG
Created February 22, 2019 22:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DaniJG/6ea83029e9e8c1f56416709467a607bc to your computer and use it in GitHub Desktop.
Save DaniJG/6ea83029e9e8c1f56416709467a607bc to your computer and use it in GitHub Desktop.
Vue global events made easy with this mixin
import { mapKeys, mapValues, kebabCase, bind, forIn } from 'lodash';
// Allows components to trigger global events using the global vue instance
// by adding a new method this.globalEmit(...), which is equivalent to this.$root.$emit(...)
// To facilitate listening to these events, allows components to declare a new events object as part of its options
// Given an component like:
// computed: { ... }
// events: {
// onScrollToView(payload){
// // do something with payload
// },
// myEvent(payload) { ... }
// ['making-my-life-hard'](payload) { ... }
// },
// methods: { ... }
// This mixin will automatically wire those functions to the events 'scroll-to-view', 'my-event' and 'making-my-life-hard'
// It converts automatically event names to kebap case (so the component declaration is nicer) and removes the 'on' prefix if foung
// When the component is destroyed this mixin will automatically clean references
const mixin = {
methods: {
globalEmit(eventName, payload){
return this.$root.$emit(eventName, payload);
}
},
beforeCreate() {
this.$options.events = this.$options.events || {};
// Allow events to be declared as "onScrollToView", and have them listening to the "scroll-to-view" event
this.$options.events = mapKeys(this.$options.events, (method, eventName) => {
if (eventName.startsWith('on')) eventName = eventName.slice(2);
return kebabCase(eventName);
});
// Ensure all the event handlers receive the component instance as "this"
this.$options.events = mapValues(this.$options.events, method => bind(method, this));
// Automatically wire all the events declared in the "events" section of the component
// so they become listeners of events in the $root instance
forIn(
this.$options.events,
(method, eventName) => this.$root.$on(eventName, method)
);
},
beforeDestroy() {
// Automatically cleanup of event listeners
forIn(
this.$options.events,
(method, eventName) => this.$root.$off(eventName, method)
);
}
};
export default mixin;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment