Created
February 22, 2019 22:21
-
-
Save DaniJG/6ea83029e9e8c1f56416709467a607bc to your computer and use it in GitHub Desktop.
Vue global events made easy with this mixin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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