Skip to content

Компонент InView

<InView> — renderless-обёртка вокруг useElementVisibility для элементов v-for, которым нужно реактивное значение isVisible/ratio прямо в шаблоне (например, чтобы лениво смонтировать тяжёлый дочерний компонент), а не просто переключение класса — для случая «только класс» без лишнего компонента см. v-reveal.

Всегда рендерит один реальный оборачивающий элемент (as, по умолчанию 'div') — IntersectionObserver нужен настоящий элемент для измерения, так что «renderless» здесь означает отсутствие навязанных стилей/поведения сверх этого, а не полное отсутствие DOM.

vue
<template>
  <InView v-for="item in items" :key="item.id" once v-slot="{ isVisible }">
    <HeavyChart v-if="isVisible" :item="item" />
  </InView>
</template>

Пропсы

once

boolean · по умолчанию: viewportDefaults.once

threshold

number | number[] · по умолчанию: viewportDefaults.threshold

rootMargin

string · по умолчанию: viewportDefaults.rootMargin

root

HTMLElement | null · по умолчанию: null

as

string · по умолчанию: 'div'

Тег для оборачивающего элемента, на котором реально измеряется видимость.

Слоты

default

{ isVisible: boolean, ratio: number }

Та же форма, что и у возвращаемого значения useElementVisibility (как простые значения, не рефы — слот перерисовывается при каждом изменении).

События

enter / leave

(info: IntersectionInfo) => void

Та же форма IntersectionInfo, что и в Движке видимости — эквивалент опций onEnter/onLeave у useElementVisibility в виде событий компонента.

Пример:

vue
<script setup lang="ts">
import { InView } from '@macrulez/inview-vue'
</script>

<template>
  <InView as="section" :threshold="0.3" @enter="onCardSeen">
    <template #default="{ isVisible, ratio }">
      <div :class="{ 'is-visible': isVisible }">{{ Math.round(ratio * 100) }}% видимо</div>
    </template>
  </InView>
</template>

threshold/rootMargin/once берут значение по умолчанию из viewportDefaults, если не переданы — так же, как useElementVisibility и v-reveal.