Skip to content

Instantly share code, notes, and snippets.

@isaaclyman
Last active September 6, 2017 18:19
Show Gist options
  • Save isaaclyman/13ee88ea044546a2470825d38b8a5802 to your computer and use it in GitHub Desktop.
Save isaaclyman/13ee88ea044546a2470825d38b8a5802 to your computer and use it in GitHub Desktop.
A reactive desktop/mobile threshold handler for consumption by computed properties in Vue.js
// We use the _.debounce method to prevent hundreds of unnecessary recalculations during click-and-drag resizing.
import * as _ from 'underscore'
import Vue, { ComponentOptions } from 'vue'
// This interface and the `as` statements at the end are the only TypeScript artifacts in this file. They can be removed
// for regular ES6 projects.
interface IResponsiveBus extends Vue {
handleResize: () => void
isMobile: boolean
}
// A sensible default for mobile/desktop is 768px; it would be simple enough to expose the actual width of the window with
// another Vue data prop.
const desktopWindowWidth = 768
// There must be a minimum 300 milliseconds between changes to the `isMobile` data prop.
const resizeEventThrottle = 300
const isMobile = _.debounce(function() {
const width = window.innerWidth
return width < desktopWindowWidth
}, resizeEventThrottle, true)
// To consume this helper, simply import ResponsiveHelper from this file and refer to `ResponsiveHelper.isMobile` in a Vue
// computed property. When isMobile changes, the property will be recalculated.
export const ResponsiveHelper = new Vue({
beforeDestroy () {
window.removeEventListener('resize', this.handleResize)
},
data () {
return {
isMobile: isMobile()
}
},
methods: {
handleResize () {
this.isMobile = isMobile()
}
},
created () {
window.addEventListener('resize', this.handleResize)
}
} as ComponentOptions<IResponsiveBus>) as IResponsiveBus
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment