Headless-загрузка изображений
useImage() — headless composable. Используйте, когда нужен конечный автомат состояния загрузки и вычисляемые атрибуты, но требуется своя разметка.
const {
status, // Ref<'idle' | 'loading' | 'loaded' | 'error'>
isLoaded, // ComputedRef<boolean>
isError, // ComputedRef<boolean>
imgAttrs, // ComputedRef<ImgAttrs> — готов для spread на <img>
observe, // (el: Ref<HTMLElement | null>) => void
onImgLoad, // () => void — вызывать из img @load
onImgError, // () => void — вызывать из img @error
} = useImage(options)Опции
src
string | SrcSet, опционален. URL изображения или объект формата.
widths
number[] · по умолчанию: []. Ширины для генерации srcset на основе ширины (w).
densities
number[] | Record<number, string>, опционален. Дескрипторы плотности (1x/2x/3x); список переиспользует src, объект даёт отдельные файлы; имеет приоритет над widths, игнорирует sizes.
sizes
string, опционален. Значение атрибута sizes (только для srcset на основе ширины).
lazy
boolean · по умолчанию: true. Включить IntersectionObserver.
rootMargin
string · по умолчанию: "200px". rootMargin для IO.
threshold
number · по умолчанию: 0. threshold для IO.
fit
ObjectFit · по умолчанию: "cover". Стиль object-fit.
maxRetries
number · по умолчанию: 0. Максимум попыток повтора при неудаче загрузки.
retryDelay
number · по умолчанию: 1000. Начальная задержка в мс; удваивается на каждом повторе.
Конечный автомат
idle → loading → loaded
→ error- При
lazy: true— переход вloading, когда наблюдаемый элемент попадает во вьюпорт (внутри используетuseLazyLoad()) - При
lazy: false— переход вloadingсразу послеonMounted
Возвращаемое значение
status
Ref<ImageStatus>. Текущее состояние загрузки.
isLoaded
ComputedRef<boolean>. true, когда status === 'loaded'.
isError
ComputedRef<boolean>. true, когда status === 'error'.
imgAttrs
ComputedRef<object>. { src, srcset?, sizes?, style } — готов для v-bind.
observe
Function. Передайте Ref<HTMLElement>, чтобы начать отслеживание пересечения.
onImgLoad
Function. Вызывайте из <img @load> для перехода в loaded.
onImgError
Function. Вызывайте из <img @error> для перехода в error.
Пример — кастомный рендер
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useImage } from '@macrulez/vue-image-kit'
const containerRef = ref<HTMLElement | null>(null)
const { status, isLoaded, imgAttrs, observe, onImgLoad, onImgError } = useImage({
src: '/photo.jpg',
widths: [400, 800, 1200],
sizes: '(max-width: 768px) 100vw, 50vw',
})
onMounted(() => {
observe(containerRef)
})
</script>
<template>
<div ref="containerRef" class="image-wrapper">
<div v-if="status === 'idle'" class="skeleton" />
<img
v-if="status === 'loading' || isLoaded"
v-bind="imgAttrs"
alt="Photo"
:class="{ visible: isLoaded }"
@load="onImgLoad"
@error="onImgError"
/>
<div v-if="status === 'error'" class="error-state">Failed to load</div>
</div>
</template>
<style scoped>
img {
opacity: 0;
transition: opacity 0.3s;
}
img.visible {
opacity: 1;
}
</style>