VUE

useWindowSize Composable

Reactive window size with debounced resize events

Vue3ComposablesWindowSizeResponsiveReactive

Code

import { ref, onMounted, onUnmounted } from 'vue';

interface WindowSize {
  width: number;
  height: number;
  isMobile: boolean;
  isTablet: boolean;
  isDesktop: boolean;
}

export function useWindowSize(debounceDelay = 100): WindowSize {
  const width = ref(window.innerWidth);
  const height = ref(window.innerHeight);
  const isMobile = ref(width.value < 768);
  const isTablet = ref(width.value >= 768 && width.value < 1024);
  const isDesktop = ref(width.value >= 1024);

  let resizeTimeout: ReturnType<typeof setTimeout> | null = null;

  const updateSize = () => {
    width.value = window.innerWidth;
    height.value = window.innerHeight;
    isMobile.value = width.value < 768;
    isTablet.value = width.value >= 768 && width.value < 1024;
    isDesktop.value = width.value >= 1024;
  };

  const handleResize = () => {
    __TOKEN_21__ (resizeTimeout) clearTimeout(resizeTimeout);
    resizeTimeout = setTimeout(updateSize, debounceDelay);
  };

  onMounted(() => {
    window.addEventListener('resize', handleResize);
    updateSize(); // Initial update
  });

  onUnmounted(() => {
    window.removeEventListener('resize', handleResize);
    __TOKEN_22__ (resizeTimeout) clearTimeout(resizeTimeout);
  });

  return {
    width: width.value,
    height: height.value,
    isMobile: isMobile.value,
    isTablet: isTablet.value,
    isDesktop: isDesktop.value
  };
}

// Usage example
// const { width, height, isMobile } = useWindowSize();
// watch([width, height], () => { /* handle resize */ });