Simple and lightweight visibility observer for vue 3, built on top of IntersectionObserver.
- 🧩 Vue 3 plugin
- 🔌 Composable API
- 🔍 Uses native
IntersectionObserver - ⚡ Supports offsets and reactivity
- 🌐 One global observer (better performance)
- 🛡️ Fully written in TypeScript
npm i vue-use-intersection-observer
main.ts
import { createApp } from 'vue';
import App from './App.vue';
import { VisibilityPlugin } from 'vue-use-intersection-observer';
const app = createApp(App);
app.use(VisibilityPlugin);
app.mount('#app');# Example with composable
<template>
<div
:style="{
position: 'fixed',
top: '20px',
right: '20px',
width: '40px',
height: '40px',
borderRadius: '50%',
backgroundColor: isvisible ? 'green' : 'red',
}"
></div>
<div style="height: 150vh"></div>
<div ref="target" style="width: 200px; height: 200px; background: gray">
Observed Element
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { useIntersectionObserver } from 'vue-use-intersection-observer';
const target = ref<HTMLElement | null>(null);
const isvisible = ref<boolean>(false);
const { observe, unobserve } = useIntersectionObserver();
onMounted(() => {
observe(target, {
once: false,
callback: (visible) => {
isvisible.value = visible;
},
});
});
onBeforeUnmount(() => {
unobserve(target);
});
</script># Example with directive
<template>
<div
:style="{
position: 'fixed',
top: '20px',
right: '20px',
width: '40px',
height: '40px',
borderRadius: '50%',
backgroundColor: isvisible ? 'green' : 'red',
}"
></div>
<div style="height: 150vh"></div>
<div
v-visible="onVisible"
style="width: 200px; height: 200px; background: gray"
>
Observed Element
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const isvisible = ref<boolean>(false);
const onVisible = (visible: boolean) => {
isvisible.value = visible;
};
</script>
The
v-visibledirective is intended for simple use cases. It only accepts a callback function and always reports the visibility state. For advanced configuration (once, offset, threshold), use the composable API. By default always tracks visibility changes (onceis implicitly set tofalse).
Composable used to observe when elements enter or leave the viewport.
const { observe, unobserve } = useIntersectionObserver();Start observing an element.
Parameters:
| Name | Type | Description | Required | Default |
|---|---|---|---|---|
| target | ref | Element ref to observe | true | — |
| options | Options | Observer configuration | true | — |
Options:
| Name | Type | Description | Required | Default |
|---|---|---|---|---|
| callback | function | Called when visibility changes | true | — |
| offset | number | Trigger before entering viewport | false | 0 |
| threshold | number or array | Intersection threshold | false | 0 |
| once | boolean | Trigger only the first time | false | true |
Stop observing a previously registered element.
| Name | Type | Description | Required | Default |
|---|---|---|---|---|
| target | ref | Element ref to stop observing | true | — |
MIT License - see LICENSE for details.
