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>

Пропы ​

src ​

string | SrcSet, опционален, если задан image. URL или объект с вариантами форматов.

image ​

ImageMeta, опционален. Метаданные, вычисленные на этапе сборки (запись из манифеста CLI или импорт ?vik) — задаёт src/width/height/hazehash/blurhash/thumbhash/placeholder/sizes. Любой явно указанный проп выше переопределяет соответствующее поле.

Если зарегистрирован манифест плейсхолдеров, его запись для src этого изображения так же заполняет width/height/hazehash/blurhash/thumbhash — после явных пропсов и image.

alt ​

string, обязателен. Атрибут alt на <img>. В dev-сборках подозрительное значение (пустое, состоящее только из пробелов, или похожее на имя файла вроде "photo.jpg") логирует console.warn — осознанный alt="" для декоративного изображения никогда его не вызывает.

width ​

number, опционален. Собственная ширина; используется для резервирования пространства под aspect-ratio.

height ​

number, опционален. Собственная высота; используется для резервирования пространства под aspect-ratio.

hazehash ​

string, опционален. Строка HazeHash из опционального пакета hazehash; декодируется по требованию в невидимый canvas в памяти и становится CSS-фоном самого элемента. Предпочтительный плейсхолдер: имеет приоритет над blurhash, thumbhash и placeholder. Если пакет не установлен, используется следующий плейсхолдер.

blurhash ​

string, опционален. Строка BlurHash; декодируется в невидимый canvas в памяти (никогда не попадает в DOM) и становится CSS-фоном самого элемента. Имеет приоритет над placeholder/thumbhash, но уступает hazehash — если blurhash задан и может отрендериться, LQIP/ThumbHash-плейсхолдер вообще не показывается (они взаимоисключающие, а не накладываются друг на друга).

thumbhash ​

string, опционален. Строка ThumbHash; декодируется в PNG data URL, используется как blur-up плейсхолдер.

placeholder ​

string, опционален. Base64 LQIP или ThumbHash data URL; переопределяет thumbhash, если заданы оба.

ssrPlaceholder ​

boolean · по умолчанию: false. Сервер отдаёт дешёвое превью вместо тяжёлой картинки: готовое превью становится CSS-фоном отрендеренного <img>, а ленивая картинка не загружается, пока не приблизится к области просмотра, — после гидрации её подставляет тот же IntersectionObserver (rootMargin), что управляет любой ленивой картинкой. Без пропса сервер отдаёт обычный <img src="…" loading="lazy">, который браузер может начать скачивать задолго до гидрации, а blur появляется только после гидрации.

У ленивой картинки серверный <img> получает прозрачный пиксель 1×1 вместо настоящего src, а настоящий <img> кладётся рядом в <noscript>, поэтому поисковики и посетители без JavaScript всё равно получают полное изображение. У нетерпеливой (lazy="false" или priority) настоящий src остаётся, а превью просто лежит фоном под ней — используйте это для картинки в начале страницы.

Превью должно быть уже готовым data: URL: проп placeholder, image.placeholder или превью, которое Vite-плагин зарегистрировал для этого src (imports: { preview }). BlurHash или ThumbHash сами по себе на сервере не декодируются (там нет canvas), поэтому если задан только хеш, проп ничего не делает. Он также игнорируется вместе с placeholderColor, placeholderMode="color" и placeholderMode="shimmer". После гидрации это же превью остаётся под картинкой, пока она не загрузится. См. Превью в серверном HTML.

placeholderMode ​

'blur' | 'color' | 'shimmer' · по умолчанию: 'blur'. 'color' показывает сплошной цвет — доминирующий цвет из манифеста плейсхолдеров или средний цвет thumbhash; 'shimmer' показывает анимированный скелетон (хэш не нужен).

placeholderColor ​

string, опционален. Явный сплошной CSS-цвет плейсхолдера; имеет приоритет и не требует декодирования.

widths ​

number[], опционален. Ширины в пикселях для автоматической генерации srcset на основе ширины (w).

densities ​

number[] | Record<number, string>, опционален. Дескрипторы плотности (1x/2x/3x) для изображений фиксированного размера. Список переиспользует src; объект даёт отдельный файл на плотность. Имеет приоритет над widths, игнорирует sizes.

sizes ​

string, опционален. Атрибут sizes, передаваемый в <img> (только для srcset на основе ширины).

breakpoints ​

BreakpointMap, опционален. Локальные брейкпоинты (сливаются с глобальными брейкпоинтами плагина).

sources ​

ResponsiveSrc, опционален. Объект брейкпоинт → URL (или { avif?, webp?, fallback }) для арт-дирекции, опционально комбинируемый с переключением формата на брейкпоинт. Запись может нести и собственные width/height и плейсхолдер (blurhash, thumbhash, placeholder, placeholderColor), которые используются, пока активен её брейкпоинт, — см. Плейсхолдеры на брейкпоинт.

lazy ​

boolean · по умолчанию: true. Включить ленивую загрузку через IntersectionObserver.

rootMargin ​

string · по умолчанию: "200px". rootMargin для IO — насколько раньше вьюпорта начинается загрузка.

threshold ​

number · по умолчанию: 0. threshold для IO — требуемая доля пересечения для срабатывания.

fit ​

ObjectFit, опционален. Значение CSS object-fit на <img>. Если задан явно, применяется всегда. Если не задан, по умолчанию используется "cover" — но только через переопределяемый CSS-класс, и только когда размер блока изображения действительно ограничен (layout="fill"/"fixed", либо заданы одновременно width и height); в остальных случаях ничего не применяется, так как object-fit не имеет эффекта без ограниченного блока.

focal ​

FocalPoint, опционален. Фокальная точка { x, y } (доли 0–1) → object-position; сохраняет объект в кадре, когда fit="cover" обрезает изображение.

maxRetries ​

number · по умолчанию: 0. Максимум попыток повтора при неудаче загрузки.

retryDelay ​

number · по умолчанию: 1000. Начальная задержка в мс; удваивается на каждом повторе (экспоненциальная задержка).

fetchpriority ​

'high' | 'low' | 'auto', опционален. Подсказка браузеру о приоритете загрузки.

decoding ​

'async' | 'sync' | 'auto' · по умолчанию: 'async'. Режим декодирования изображения.

priority ​

boolean · по умолчанию: false. Сокращение для LCP/hero-изображения — форсирует lazy=false, fetchpriority='high', decoding='sync'. Не автоматическое определение LCP (это ненадёжно до отрисовки) — отметьте именно то изображение, которое важно, вместо ручной установки трёх пропов.

respectSaveData ​

boolean · по умолчанию: false. На соединении с экономией трафика: нейтрализует priority (остаётся lazy) и понижает src до наименьшего доступного URL из densities/image.srcset. См. Адаптация к сети.

layout ​

'fixed' | 'responsive' | 'fill', опционален. Пресет размещения — применяется напрямую к элементу, который сейчас показывает картинку (никакой обёртки нет, см. Компоновка без обёртки). Если не задан, поведение полностью идентично 'responsive' — включая автогенерацию sizes. См. Пресеты раскладки.

cdn ​

boolean | AutoLoaderConfig, опционален. Опционально: пропускает строковый src через autoLoader() — определяет CDN по URL и переписывает его, без ручной настройки адаптера. См. CDN-адаптеры → Автоопределение CDN с VImage.

loader ​

'server', опционален. Опционально: пропускает строковый src через обработчик самостоятельного сервера по запросу, используя buildImageUrl(). См. Самостоятельный сервер по запросу → Подключение VImage к нему.

loaderRoute ​

string · по умолчанию: /_vik/image. Переопределение маршрута для loader="server" — имеет приоритет над значением по умолчанию serverRoute плагина/модуля Nuxt.

fadeIn ​

boolean · по умолчанию: false. Плавное появление блока целиком (opacity 0→1, ~0.3с) вскоре после монтирования — не привязано конкретно к моменту загрузки фото. Плейсхолдер и фото рисуются на одном и том же элементе (фон + содержимое), поэтому fadeIn плавно проявляет весь блок целиком, а не «блюр сквозь проступающее резкое фото» — как только фото готово, оно мгновенно перекрывает фон-плейсхолдер под собой. По умолчанию выключен: переключение плейсхолдер → фото происходит мгновенно.

События ​

@load ​

Event. Срабатывает при завершении загрузки изображения.

@error ​

Event. Срабатывает при неудаче загрузки изображения.

Слоты ​

#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/hazehash/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 }"
/>

Самый дешёвый плейсхолдер — сплошной средний цвет (без декодирования, 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
<!-- По умолчанию переключение плейсхолдер → фото мгновенное. fadeIn
     добавляет лёгкое opacity-появление всего блока целиком. -->
<VImage
  src="/photo.jpg"
  alt="Gallery item"
  :width="600"
  :height="400"
  blurhash="LEHV6nWB2yk8pyo0adR*.7kCMdnj"
  fade-in
/>

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

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>