Компонент InView
<InView> — renderless-обёртка вокруг useElementVisibility для элементов v-for, которым нужно реактивное значение isVisible/ratio прямо в шаблоне (например, чтобы лениво смонтировать тяжёлый дочерний компонент), а не просто переключение класса — для случая «только класс» без лишнего компонента см. v-reveal.
Всегда рендерит один реальный оборачивающий элемент (as, по умолчанию 'div') — IntersectionObserver нужен настоящий элемент для измерения, так что «renderless» здесь означает отсутствие навязанных стилей/поведения сверх этого, а не полное отсутствие DOM.
<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 в виде событий компонента.
Пример:
<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.