v-intersect

Директива v-intersect является мощным инструментом для отслеживания появления элементов в зоне видимости пользователя. Она основана на Intersection Observer API и позволяет эффективно управлять поведением компонентов при их появлении или исчезновении на экране без необходимости постоянного прослушивания событий прокрутки.


Основные свойства и синтаксис

Синтаксис использования выглядит следующим образом:

<div v-intersect="options" @intersect="handler">
  Контент
</div>
  • options — объект настроек Intersection Observer. Содержит:

    • threshold — число или массив чисел от 0 до 1, определяющее долю видимости элемента для срабатывания события.
    • root — элемент, относительно которого определяется видимость. По умолчанию null (всё окно просмотра).
    • rootMargin — строка, задающая отступы вокруг корневого элемента, влияющие на триггер срабатывания. Формат: '10px 20px 30px 40px'.
  • @intersect — событие, которое вызывается при изменении видимости элемента. Передает объект с параметрами:

    • isIntersecting — логическое значение, указывающее, виден ли элемент.
    • entry — объект IntersectionObserverEntry, содержащий детальную информацию о наблюдаемом элементе.

Настройка threshold

Параметр threshold позволяет точно контролировать момент срабатывания. Примеры:

<div v-intersect="{ threshold: 0.5 }" @intersect="onIntersect">
  Элемент появляется, когда видна половина
</div>

<div v-intersect="{ threshold: [0, 0.25, 0.5, 0.75, 1] }" @intersect="onIntersectMultiple">
  Элемент с множественными порогами
</div>
  • Значение 0 означает срабатывание при любом появлении элемента.
  • Значение 1 срабатывает только когда элемент полностью виден.
  • Массив порогов позволяет получать уведомления на нескольких стадиях видимости.

Использование root и rootMargin

root позволяет задать контейнер, относительно которого отслеживается видимость. Это удобно для внутренних скролл-блоков:

<div class="scroll-container" ref="container">
  <div v-intersect="{ root: $refs.container, threshold: 0.5 }" @intersect="onIntersect">
    Элемент внутри прокручиваемого блока
  </div>
</div>

rootMargin позволяет смещать границы триггера:

<div v-intersect="{ rootMargin: '0px 0px -100px 0px' }" @intersect="onIntersect">
  Элемент с отрицательным отступом снизу
</div>

Отрицательные значения позволяют срабатывать раньше, положительные — позже.


Отслеживание повторного пересечения

По умолчанию событие @intersect срабатывает при каждом пересечении. Для однократного срабатывания используется модификатор .once:

<div v-intersect.once="{ threshold: 0.5 }" @intersect="onFirstIntersect">
  Срабатывает только один раз
</div>

Это особенно полезно для анимаций, которые должны проигрываться только при первом появлении.


Взаимодействие с анимациями и lazy loading

Директива v-intersect широко применяется для:

  • Lazy loading изображений:
<img
  v-intersect.once="{ threshold: 0.1 }"
  @intersect="loadImage"
  :src="placeholder"
/>
  • Активации анимаций при появлении:
<div
  v-intersect="{ threshold: 0.2 }"
  @intersect="animateElement"
  :class="{ 'animate-fade-in': isVisible }"
>
  Контент с анимацией
</div>
  • Загрузки данных при скролле:
<div v-intersect="{ threshold: 1 }" @intersect="loadMoreItems">
  Загрузка следующей страницы
</div>

Примеры сложных конфигураций

  1. Комбинация нескольких порогов и кастомного root:
<div class="viewport" ref="viewport">
  <div
    v-intersect="{ root: $refs.viewport, threshold: [0, 0.25, 0.5, 0.75, 1], rootMargin: '0px 0px -50px 0px' }"
    @intersect="handleIntersect"
  >
    Контент с детальной аналитикой видимости
  </div>
</div>
  1. Условная обработка на основе видимости:
methods: {
  handleIntersect({ isIntersecting, entry }) {
    if (isIntersecting && entry.intersectionRatio > 0.5) {
      this.startAnimation()
    }
  }
}

Особенности и рекомендации

  • Производительность: Использование v-intersect значительно эффективнее классического отслеживания прокрутки через события scroll.
  • Компоновка компонентов: Вложенные наблюдатели работают корректно, если правильно заданы root.
  • Совместимость: Директива основана на современном API, требуется поддержка браузеров с IntersectionObserver. Для старых версий можно использовать полифиллы.

Итоговый подход к применению

v-intersect позволяет управлять видимостью элементов динамически, запускать анимации, загружать ресурсы и отслеживать скролл без дополнительной нагрузки на рендеринг. Гибкие параметры threshold, root и rootMargin обеспечивают точный контроль, а модификатор .once и событие @intersect делают взаимодействие с DOM удобным и предсказуемым.

Это делает v-intersect незаменимым инструментом при разработке интерфейсов с большим количеством визуально динамических элементов.