VUE

useElementSize Composable

Reactive element size monitoring using ResizeObserver with cleanup

Vue3ComposablesResizeObserverElementSizeReactive

Code

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

interface ElementSize {
  width: Ref<number>;
  height: Ref<number>;
}

export function useElementSize(target: Ref<HTMLElement | null>): ElementSize {
  const width = ref(0);
  const height = ref(0);
  let observer: ResizeObserver | null = null;

  const updateSize = (entries: ResizeObserverEntry[]) => {
    const entry = entries[0];
    __TOKEN_21__ (entry) {
      width.value = entry.contentRect.width;
      height.value = entry.contentRect.height;
    }
  };

  onMounted(() => {
    __TOKEN_22__ (!target.value || !ResizeObserver) return;

    // Initialize with current size
    width.value = target.value.offsetWidth;
    height.value = target.value.offsetHeight;

    // Create observer
    observer = new ResizeObserver(updateSize);
    observer.observe(target.value);
  });

  onUnmounted(() => {
    __TOKEN_25__ (observer && target.value) {
      observer.unobserve(target.value);
      observer.disconnect();
    }
  });

  return { width, height };
}

// Usage example
// const containerRef = ref<HTMLElement | null>(null);
// const { width, height } = useElementSize(containerRef);
// watch([width, height], ([newWidth, newHeight]) => {
//   console.log('Element size changed:', newWidth, newHeight);
// });

// Template: <div ref="containerRef">Content</div>