useResizeObserver
A composable for detecting element size changes using the Resize Observer API with automatic cleanup.
Usage
The useResizeObserver composable wraps the Resize Observer API to detect when an element’s dimensions change. It’s useful for responsive components, charts, virtualized lists, and aspect ratio maintenance.
vue
<script setup lang="ts">
import { useResizeObserver } from '@vuetify/v0'
import { ref, useTemplateRef } from 'vue'
const container = useTemplateRef('container')
const width = ref(0)
const height = ref(0)
useResizeObserver(container, (entries) => {
const entry = entries[0]
width.value = entry.contentRect.width
height.value = entry.contentRect.height
})
</script>
<template>
<div ref="container" class="resizable">
<p>Width: {{ width }}px</p>
<p>Height: {{ height }}px</p>
</div>
</template>Architecture
useResizeObserver wraps the native ResizeObserver API with Vue reactivity:
Reactivity
| Property/Method | Reactive | Notes |
|---|---|---|
isActive | Computed from observer ref | |
isPaused | ShallowRef, readonly | |
target | Accepts MaybeRef, watched for changes |
useElementSize
| Property/Method | Reactive | Notes |
|---|---|---|
width | ShallowRef | |
height | ShallowRef |
Examples
0 x 0
Analytics
Users
Revenue
Orders
Messages
Settings
Drag the right edge to resize. Columns: 1
<script setup lang="ts">
import { useResizeObserver } from '@vuetify/v0'
import { computed, shallowRef, useTemplateRef } from 'vue'
const containerRef = useTemplateRef<HTMLElement>('container')
const width = shallowRef(0)
const height = shallowRef(0)
useResizeObserver(containerRef, entries => {
const entry = entries[0]
if (entry) {
width.value = entry.contentRect.width
height.value = entry.contentRect.height
}
})
const columns = computed(() => {
if (width.value >= 600) return 3
if (width.value >= 400) return 2
return 1
})
const cards = [
{ title: 'Analytics', icon: 'i-lucide-bar-chart-2', color: 'bg-primary' },
{ title: 'Users', icon: 'i-lucide-users', color: 'bg-secondary' },
{ title: 'Revenue', icon: 'i-lucide-dollar-sign', color: 'bg-success' },
{ title: 'Orders', icon: 'i-lucide-shopping-cart', color: 'bg-warning' },
{ title: 'Messages', icon: 'i-lucide-mail', color: 'bg-info' },
{ title: 'Settings', icon: 'i-lucide-settings', color: 'bg-accent' },
]
</script>
<template>
<div class="flex flex-col gap-4">
<div
ref="container"
class="relative min-h-64 p-4 border-2 border-dashed border-divider rounded-lg resize-x overflow-auto"
style="min-width: 200px; max-width: 100%"
>
<div
class="absolute top-2 right-2 px-2 py-1 rounded text-xs font-mono bg-surface-variant text-on-surface-variant z-10"
>
{{ Math.round(width) }} x {{ Math.round(height) }}
</div>
<div
class="grid gap-3 transition-all duration-300"
:style="{ gridTemplateColumns: `repeat(${columns}, 1fr)` }"
>
<div
v-for="card in cards"
:key="card.title"
class="p-4 rounded-lg bg-surface border border-divider shadow-sm transition-transform duration-200 hover:scale-[1.02]"
>
<div class="flex items-center gap-3">
<div
class="w-10 h-10 rounded-lg flex items-center justify-center text-white"
:class="card.color"
>
<div class="w-5 h-5" :class="card.icon" />
</div>
<span class="font-medium text-on-surface">{{ card.title }}</span>
</div>
</div>
</div>
</div>
<p class="text-xs text-on-surface-variant text-center">
Drag the right edge to resize. Columns: {{ columns }}
</p>
</div>
</template>
The following API details are for the useResizeObserver composable.
Functions
useResizeObserver
(target: MaybeElementRef, callback: (entries: ResizeObserverEntry[]) => void, options?: ResizeObserverOptions) => UseResizeObserverReturnA composable that uses the Resize Observer API to detect when an element's size changes.
useElementSize
(target: MaybeElementRef) => UseElementSizeReturnA convenience composable that uses the Resize Observer API to track an element's size.
Options
Properties
isActive
Readonly<Ref<boolean, boolean>>Whether the observer is currently active (created and observing)
Methods
Was this page helpful?