Skip to content

VImage

Основной компонент. Объединяет ленивую загрузку, плейсхолдер, переключение форматов и переходы в одном элементе.

vue
<VImage
  src="/photo.jpg"
  alt="Описание"
  :width="1200"
  :height="600"
  blurhash="LEHV6nWB2yk8pyo0adR*.7kCMdnj"
  placeholder="data:image/jpeg;base64,..."
  :widths="[400, 800, 1200]"
  sizes="(max-width: 768px) 100vw, 50vw"
  :lazy="true"
  root-margin="300px"
  fit="cover"
  @load="onLoad"
  @error="onError"
>
  <template #error>
    <div class="my-error">Image failed to load</div>
  </template>
</VImage>

Пропы

ПропТипПо умолчаниюОписание
srcstring | SrcSetURL или объект с вариантами форматов. Опционален, если задан image
imageImageMetaМетаданные, вычисленные на этапе сборки (запись из манифеста CLI или импорт ?vik) — задаёт src/width/height/blurhash/thumbhash/placeholder/sizes. Любой явно указанный проп выше переопределяет соответствующее поле
altstringОбязателен. Атрибут alt на <img>. В dev-сборках подозрительное значение (пустое, состоящее только из пробелов, или похожее на имя файла вроде "photo.jpg") логирует console.warn — осознанный alt="" для декоративного изображения никогда его не вызывает
widthnumberСобственная ширина; используется для резервирования пространства под aspect-ratio
heightnumberСобственная высота; используется для резервирования пространства под aspect-ratio
blurhashstringСтрока BlurHash; декодируется в canvas внутри onMounted
thumbhashstringСтрока ThumbHash; декодируется в PNG data URL, используется как blur-up плейсхолдер
placeholderstringBase64 LQIP или ThumbHash data URL; переопределяет thumbhash, если заданы оба
placeholderMode'blur' | 'color' | 'shimmer''blur''color' показывает сплошной средний цвет (из thumbhash); 'shimmer' показывает анимированный скелетон (хэш не нужен)
placeholderColorstringЯвный сплошной CSS-цвет плейсхолдера; имеет приоритет и не требует декодирования
widthsnumber[]Ширины в пикселях для автоматической генерации srcset на основе ширины (w)
densitiesnumber[] | Record<number, string>Дескрипторы плотности (1x/2x/3x) для изображений фиксированного размера. Список переиспользует src; объект даёт отдельный файл на плотность. Имеет приоритет над widths, игнорирует sizes
sizesstringАтрибут sizes, передаваемый в <img> (только для srcset на основе ширины)
breakpointsBreakpointMapЛокальные брейкпоинты (сливаются с глобальными брейкпоинтами плагина)
sourcesResponsiveSrcОбъект брейкпоинт → URL (или { avif?, webp?, fallback }) для арт-дирекции, опционально комбинируемый с переключением формата на брейкпоинт
lazybooleantrueВключить ленивую загрузку через IntersectionObserver
rootMarginstring"200px"rootMargin для IO — насколько раньше вьюпорта начинается загрузка
thresholdnumber0threshold для IO — требуемая доля пересечения для срабатывания
fitObjectFit"cover"Значение CSS object-fit на <img>
focalFocalPointФокальная точка { x, y } (доли 0–1) → object-position; сохраняет объект в кадре, когда fit="cover" обрезает изображение
maxRetriesnumber0Максимум попыток повтора при неудаче загрузки
retryDelaynumber1000Начальная задержка в мс; удваивается на каждом повторе (экспоненциальная задержка)
fetchpriority'high' | 'low' | 'auto'Подсказка браузеру о приоритете загрузки
decoding'async' | 'sync' | 'auto''async'Режим декодирования изображения
prioritybooleanfalseСокращение для LCP/hero-изображения — форсирует lazy=false, fetchpriority='high', decoding='sync'. Не автоматическое определение LCP (это ненадёжно до отрисовки) — отметьте именно то изображение, которое важно, вместо ручной установки трёх пропов
respectSaveDatabooleanfalseНа соединении с экономией трафика: нейтрализует priority (остаётся lazy) и понижает src до наименьшего доступного URL из densities/image.srcset. См. Адаптация к сети
layout'fixed' | 'responsive' | 'fill'Пресет размещения обёртки. Если не задан, сохраняется текущее поведение по умолчанию (заполняет ширину контейнера, aspect-ratio сохраняется). См. Пресеты раскладки
cdnboolean | AutoLoaderConfigОпционально: пропускает строковый src через autoLoader() — определяет CDN по URL и переписывает его, без ручной настройки адаптера. См. Автоопределение CDN с VImage
loader'server'Опционально: пропускает строковый src через обработчик vue-image-kit/server по запросу, используя buildImageUrl(). См. Подключение VImage к нему
loaderRoutestring/_vik/imageПереопределение маршрута для loader="server" — имеет приоритет над значением по умолчанию serverRoute плагина/модуля Nuxt

События

СобытиеPayloadОписание
@loadEventСрабатывает при завершении загрузки изображения
@errorEventСрабатывает при неудаче загрузки изображения

Слоты

СлотОписание
#errorКастомный UI, показываемый при неудаче загрузки. Если не задан, показывается серый прямоугольник с иконкой битого изображения.

Примеры

Простое изображение с ленивой загрузкой:

vue
<VImage src="/photo.jpg" alt="Landscape" />

С blurhash и размерами для резервирования aspect-ratio:

vue
<VImage
  src="/photo.jpg"
  alt="Landscape"
  :width="1200"
  :height="800"
  blurhash="LEHV6nWB2yk8pyo0adR*.7kCMdnj"
/>

WebP/AVIF с srcset и blur-up:

vue
<VImage
  :src="{ avif: '/photo.avif', webp: '/photo.webp', fallback: '/photo.jpg' }"
  alt="Product"
  :width="800"
  :height="600"
  placeholder="data:image/jpeg;base64,/9j/4AAQSkZJRgAB..."
  :widths="[400, 800]"
  sizes="(max-width: 640px) 100vw, 800px"
/>

Отключение ленивой загрузки для изображений над первым экраном:

vue
<VImage src="/hero.jpg" alt="Hero" :lazy="false" />

LCP/hero-изображение — priority вместо трёх отдельных пропов:

vue
<VImage src="/hero.jpg" alt="Hero" :width="1600" :height="900" priority />

Из вывода CLI/манифеста — без ручной настройки пропов:

vue
<script setup lang="ts">
import meta from './photo.jpg?vik' // или: import { images } from './assets/images'
</script>

<template>
  <!-- src/width/height/blurhash/thumbhash/placeholder/sizes — всё из meta -->
  <VImage :image="meta" alt="Product photo" />
</template>

Фокальная точка — сохранить объект в кадре при обрезке:

vue
<!-- При fit="cover" изображение обрезается под рамку; focal определяет,
     какая часть выживает. { x: 0.5, y: 0.3 } отдаёт приоритет верхней середине (например, лицу). -->
<VImage
  src="/portrait.jpg"
  alt="Team member"
  :width="400"
  :height="400"
  fit="cover"
  :focal="{ x: 0.5, y: 0.3 }"
/>

Самый дешёвый плейсхолдер — сплошной средний цвет (без canvas, 0 байт):

vue
<!-- Режим 'color' берёт средний RGBA прямо из заголовка ThumbHash. -->
<VImage
  src="/photo.jpg"
  alt="Gallery item"
  :width="600"
  :height="400"
  thumbhash="3OcRJYB4d3h/iIeHeEh3eIhw+j5n"
  placeholder-mode="color"
/>

<!-- Или явный цвет, который вы уже знаете — ThumbHash вообще не нужен. -->
<VImage src="/photo.jpg" alt="Banner" placeholder-color="#1e3a8a" />

Анимированный скелетон — когда хэша нет вообще:

vue
<!-- CSS shimmer-переход до загрузки изображения. Учитывает prefers-reduced-motion. -->
<VImage src="/photo.jpg" alt="Card" :width="400" :height="300" placeholder-mode="shimmer" />

Кастомный слот ошибки:

vue
<VImage src="/missing.jpg" alt="Missing">
  <template #error>
    <div class="placeholder">
      <span>📷</span>
      <p>Image unavailable</p>
    </div>
  </template>
</VImage>

Обработка событий:

vue
<script setup lang="ts">
function onLoad(e: Event) {
  console.log('Image loaded', e)
}
function onError(e: Event) {
  console.warn('Image failed', e)
}
</script>

<template>
  <VImage src="/photo.jpg" alt="Photo" @load="onLoad" @error="onError" />
</template>