Skip to content

Instantly share code, notes, and snippets.

@loilo
Created February 20, 2020 12:23
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 loilo/86cc0ccde8e818849d58b84569d387e5 to your computer and use it in GitHub Desktop.
Save loilo/86cc0ccde8e818849d58b84569d387e5 to your computer and use it in GitHub Desktop.
Vue Page-Wide Events

Vue Page-Wide Events

This is a Vue mixin factory for handling events that occur outside of your Vue component. Listeners are detached automatically when the component is destroyed.

import on from 'events.mjs'

new Vue({
  mixins: {
    // With callback closure
    on(window, 'resize', function(event) {
      // Handle resize
    }),
    
    // With method name
    on(document, 'visibilitychange', 'handleVisibilityChange')
  },
  methods: {
    handleVisibilityChange(event) {
      // Handle visibility change
    }
  }
})

Note that the above code may throw an error in an SSR environment (e.g. with Nuxt) because window does not exist on the server side. To work around this, instead of passing the window object directly, you may instead pass a function returning the window:

on(() => window, 'resize', function() {
  // ...
})
export default function on(target, event, listener) {
let targetObject, boundListener
return {
mounted() {
// Allow functions for client-only targets
targetObject = typeof target === 'function' ? target() : target
if (typeof listener === 'string') {
// If a string is passed as a listener, use a method with that name
boundListener = this[listener]
} else {
// If listener is a function, create a version of it bound to the Vue instance
boundListener = listener.bind(this)
}
targetObject.addEventListener(event, boundListener)
},
destroyed() {
targetObject.removeEventListener(event, boundListener)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment