Components
OnClickOutside
vue
<script setup lang="ts">
const count = ref(0);
</script>
<template>
<OnClickOutside
@trigger="count++"
>
<div>
Click Outside of Me
</div>
<div>
Count: {{ count }}
</div>
</OnClickOutside>
</template>
UseActiveElement
Active element is
vue
<template>
<UseActiveElement v-slot="{ element }">
Active element is {{ element?.tagName }}
</UseActiveElement>
</template>
UseBattery
Is Charging: false
vue
<template>
<UseBattery v-slot="{ charging }">
Is Charging: {{ charging }}
</UseBattery>
</template>
UseClipboard
vue
<template>
<UseClipboard
v-slot="{ copy, copied }"
source="copy me"
>
<b-button
color="button"
@click="copy()"
>
{{ copied ? 'Copied' : 'Copy' }}
</b-button>
</UseClipboard>
</template>
UseDeviceMotion
vue
<template>
<ClientOnly>
<UseDeviceMotion v-slot="{ acceleration }">
<JsonView :data="acceleration" />
Acceleration: {{ acceleration.x }}, {{ acceleration.y }}, {{ acceleration.z }}, {{ acceleration.interval }}
</UseDeviceMotion>
</ClientOnly>
</template>
UseDeviceOrientation
vue
<template>
<ClientOnly>
<UseDeviceOrientation v-slot="{ alpha, beta, gamma }">
Alpha: {{ alpha }}
Beta: {{ beta }}
Gamma: {{ gamma }}
</UseDeviceOrientation>
</ClientOnly>
</template>
UseDevicePixelRatio
vue
<template>
<ClientOnly>
<UseDevicePixelRatio v-slot="{ pixelRatio }">
Pixel Ratio: {{ pixelRatio }}
</UseDevicePixelRatio>
</ClientOnly>
</template>
UseDeviceList
vue
<template>
<ClientOnly>
<UseDevicesList v-slot="{ videoInputs, audioInputs, audioOutputs }">
<div>Cameras: {{ videoInputs }}</div>
<div>Microphones: {{ audioInputs }}</div>
<div>Speakers: {{ audioOutputs }}</div>
</UseDevicesList>
</ClientOnly>
</template>
UseDocumentVisibility
vue
<template>
<ClientOnly>
<UseDocumentVisibility v-slot="{ visibility }">
Document Visibility: {{ visibility }}
</UseDocumentVisibility>
</ClientOnly>
</template>
UseDocumentVisibility
Fixed
Drag me! I am at 100, 100
vue
<script setup lang="ts">
const fixed = ref(false);
const style = computed(() => fixed.value ? 'position: fixed' : '');
</script>
<template>
<b-input
v-model="fixed"
type="checkbox"
/>
Fixed
<UseDraggable
v-slot="{ x, y }"
:initial-value="{ x: 100, y: 100 }"
:style="style"
>
Drag me! I am at {{ x }}, {{ y }}
</UseDraggable>
</template>
UseElementBounding
{ "height": 0, "bottom": 0, "left": 0, "right": 0, "top": 0, "width": 0, "x": 0, "y": 0 }
vue
<template>
<UseElementBounding
v-slot="eb"
style="display: inline-block; border: black solid 1px; padding:10px;"
>
<JsonView :data="eb" />
<textarea
readonly
style="resize: both; min-width: 300px;"
/>
</UseElementBounding>
</template>
UseElementSize
Width: Height:
vue
<template>
<UseElementSize v-slot="{ width, height }">
Width: {{ width }} Height: {{ height }}
</UseElementSize>
</template>
UseElementVisibility
Is Visible: false
vue
<template>
<UseElementVisibility v-slot="{ isVisible }">
Is Visible: {{ isVisible }}
</UseElementVisibility>
</template>
UseEyeDropper
vue
<template>
<ClientOnly>
<UseEyeDropper
v-slot="{ isSupported, sRGBHex, open }"
>
<b-button
color="primary"
:disabled="!isSupported"
@click="open"
>
Eye Dropper
</b-button>
<div>
sRGBHex: {{ sRGBHex }}
</div>
</UseEyeDropper>
</ClientOnly>
</template>
UseFullscreen
vue
<template>
<UseFullscreen v-slot="{ toggle }">
<video
src="/pexels/movie/3209211-uhd_3840_2160_25fps.mp4"
class="image-fluid w-100"
controls
/>
<b-button
color="primary"
@click="toggle"
>
Go Fullscreen
</b-button>
</UseFullscreen>
</template>
UseGeolocation
Latitude: Infinity Longitude: Infinity
vue
<template>
<UseGeolocation v-slot="{ coords: { latitude, longitude } }">
Latitude: {{ latitude }}
Longitude: {{ longitude }}
</UseGeolocation>
</template>
UseIdle
Is Idle: false
vue
<template>
<UseIdle
v-slot="{ idle }"
:timeout="5 * 60 * 1000"
>
Is Idle: {{ idle }}
</UseIdle>
</template>
UseMouseInElement
x: 0 y: 0 Is Outside: true
vue
<template>
<UseMouseInElement v-slot="{ elementX, elementY, isOutside }">
x: {{ elementX }}
y: {{ elementY }}
Is Outside: {{ isOutside }}
</UseMouseInElement>
</template>
UseMousePressed
Is Pressed: false
vue
<template>
<UseMousePressed v-slot="{ pressed }">
Is Pressed: {{ pressed }}
</UseMousePressed>
</template>
UseNetwork
vue
<template>
<ClientOnly>
<UseNetwork v-slot="networkStatus">
<JsonView :data="networkStatus" />
</UseNetwork>
</ClientOnly>
</template>
UseNow
vue
<template>
<ClientOnly>
<UseNow v-slot="{ now, pause, resume }">
{{ now }}
<b-button
color="primary"
@click="pause()"
>
Pause
</b-button>
<b-button
color="primary"
@click="resume()"
>
Resume
</b-button>
</UseNow>
</ClientOnly>
</template>
UseObjectUrl
vue
<template>
<ClientOnly>
<UseNow v-slot="{ now, pause, resume }">
{{ now }}
<b-button
color="primary"
@click="pause()"
>
Pause
</b-button>
<b-button
color="primary"
@click="resume()"
>
Resume
</b-button>
</UseNow>
</ClientOnly>
</template>
UseOffsetPagination
total:
80
pageCount:
8
currentPageSize:
10
currentPage:
1
isFirstPage:
true
isLastPage:
false
id | name |
vue
<script setup lang="ts">
interface User {
id: number;
name: string;
}
const database = ref([]) as Ref<User[]>;
for (let i = 0; i < 80; i++)
database.value.push({ id: i, name: `user ${i}` });
function fetch(page: number, pageSize: number) {
return new Promise<User[]>((resolve, reject) => {
const start = (page - 1) * pageSize;
const end = start + pageSize;
setTimeout(() => {
resolve(database.value.slice(start, end));
}, 100);
});
}
const data: Ref<User[]> = ref([]);
const page = ref(1);
const pageSize = ref(10);
fetchData({
currentPage: page.value,
currentPageSize: pageSize.value,
});
function fetchData({ currentPage, currentPageSize }: { currentPage: number; currentPageSize: number }) {
fetch(currentPage, currentPageSize).then((responseData) => {
data.value = responseData;
});
}
</script>
<template>
<UseOffsetPagination
v-slot="{
currentPage,
currentPageSize,
next,
prev,
pageCount,
isFirstPage,
isLastPage,
}"
:total="database.length"
@page-change="fetchData"
@page-size-change="fetchData"
>
<Grid
:columns="2"
display="inline-grid"
>
<div opacity="50">
total:
</div>
<div>{{ database.length }}</div>
<div opacity="50">
pageCount:
</div>
<div>{{ pageCount }}</div>
<div opacity="50">
currentPageSize:
</div>
<div>{{ currentPageSize }}</div>
<div opacity="50">
currentPage:
</div>
<div>{{ currentPage }}</div>
<div opacity="50">
isFirstPage:
</div>
<div>{{ isFirstPage }}</div>
<div opacity="50">
isLastPage:
</div>
<div>{{ isLastPage }}</div>
</Grid>
<div>
<b-button
:disabled="isFirstPage"
color="outline-primary"
@click="prev"
>
prev
</b-button>
<b-button
:disabled="isLastPage"
color="outline-primary"
@click="next"
>
next
</b-button>
</div>
</UseOffsetPagination>
<b-table
small
striped
>
<thead>
<tr>
<td>id</td>
<td>name</td>
</tr>
</thead>
<tbody>
<tr
v-for="d in data"
:key="d.id"
>
<td>{{ d.id }}</td>
<td>{{ d.name }}</td>
</tr>
</tbody>
</b-table>
</template>
UseOnline
vue
<template>
<ClientOnly>
<UseOnline v-slot="{ isOnline }">
Is Online: {{ isOnline }}
</UseOnline>
</ClientOnly>
</template>
UsePageLeave
Has Left Page: false
vue
<template>
<UsePageLeave v-slot="{ isLeft }">
Has Left Page: {{ isLeft }}
</UsePageLeave>
</template>
UsePointer
vue
<template>
<ClientOnly>
<UsePointer v-slot="pointer">
<JsonView :data="pointer" />
</UsePointer>
</ClientOnly>
</template>
UsePointerLock
vue
<template>
<ClientOnly>
<UsePointerLock v-slot="pointerLock">
<JsonView :data="pointerLock" />
</UsePointerLock>
</ClientOnly>
</template>
UseTimeAgo
vue
<template>
<ClientOnly>
<UseTimeAgo
v-slot="{ timeAgo }"
:time="new Date(2021, 0, 1)"
>
Time Ago: {{ timeAgo }}
</UseTimeAgo>
</ClientOnly>
</template>
UseTimestamp
vue
<template>
<ClientOnly>
<UseTimestamp v-slot="{ timestamp }">
Current Time: {{ timestamp }}
</UseTimestamp>
</ClientOnly>
</template>
UseWindowFocus
vue
<template>
<ClientOnly>
<UseWindowFocus v-slot="{ focused }">
Document Focus: {{ focused }}
</UseWindowFocus>
</ClientOnly>
</template>
UseWindowSize
Width: Infinity
Height: Infinity
vue
<template>
<UseWindowSize v-slot="{ width, height }">
<div>Width: {{ width }}</div>
<div>Height: {{ height }}</div>
</UseWindowSize>
</template>
Directives
OnLongPress
Long Pressed: false
vue
<script setup lang="ts">
const longPressedComponent = ref(false);
function onLongPressCallbackDirective(e: PointerEvent) {
longPressedComponent.value = true;
}
function resetComponent() {
longPressedComponent.value = false;
}
</script>
<template>
<p>Long Pressed: {{ longPressedComponent }}</p>
<b-button
v-on-long-press.prevent="onLongPressCallbackDirective"
mergin="l-2"
color="primary"
class="ml-2"
>
Press long
</b-button>
<b-button
mergin="l-2"
color="secondary"
class="ml-2"
@click="resetComponent"
>
Reset
</b-button>
</template>
OnClickOutside
vue
<script setup lang="ts">
const modal = ref(false);
function closeModal() {
modal.value = false;
}
</script>
<template>
<b-button
color="primary"
@click="modal = true"
>
Open Modal
</b-button>
<div
v-if="modal"
v-on-click-outside="closeModal"
>
Hello World
</div>
</template>
OnKeyStroke
vue
<script setup lang="ts">
const storoke = ref('');
function onUpdate(e: KeyboardEvent) {
console.log(e);
storoke.value = storoke.value + e.key;
}
</script>
<template>
<div class="mb-3">
<BFormLabel>
Type C
</BFormLabel>
<BFormInput v-on-key-stroke:c,v="onUpdate" />
</div>
<div class="mb-3">
<BFormLabel>
With Options
</BFormLabel>
<BFormInput v-on-key-stroke:c,v="[onUpdate, { eventName: 'keyup' }]" />
</div>
<div>{{ storoke }}</div>
</template>
ElementHover
vue
<script setup lang="ts">
const isHovered = ref(false);
function onHover(hovered: boolean) {
isHovered.value = hovered;
}
</script>
<template>
<b-button color="primary" v-element-hover="[onHover, { delayEnter: 1000 }]">
<span>{{ isHovered ? 'Thank you!' : 'Hover me' }}</span>
</b-button>
</template>
ElementSize
0 0
vue
<script setup lang="ts">
const width1 = ref(0);
const height1 = ref(0);
function onResize({ width, height }: { width: number; height: number }) {
width1.value = width;
height1.value = height;
}
</script>
<template>
<textarea v-element-size="onResize" />
<!-- with options -->
<textarea v-element-size="[onResize, { width: 100, height: 100 }, { box: 'content-box' }]" />
<div>{{ width1 }} {{ height1 }}</div>
</template>
ElementVisibility
outside
outside
vue
<script setup>
const target = ref(null);
const isVisible = ref(false);
function onElementVisibility(state) {
isVisible.value = state;
}
</script>
<template>
<div v-element-visibility="onElementVisibility">
{{ isVisible ? 'inside' : 'outside' }}
</div>
<!-- with options -->
<div ref="target">
<div v-element-visibility="[onElementVisibility, { scrollTarget: target }]">
{{ isVisible ? 'inside' : 'outside' }}
</div>
</div>
</template>
InfiniteScroll
1
2
3
4
5
6
1
2
3
4
5
6
vue
<script setup lang="ts">
const data = ref([1, 2, 3, 4, 5, 6]);
function onLoadMore() {
const length = data.value.length + 1;
data.value.push(...Array.from({ length: 5 }, (_, i) => length + i));
}
</script>
<template>
<b-div
v-infinite-scroll="onLoadMore"
overflow="auto"
class="un-h-200px"
>
<div
v-for="item in data"
:key="item"
>
{{ item }}
</div>
</b-div>
<!-- with options -->
<b-div
v-infinite-scroll="[onLoadMore, { distance: 10 }]"
overflow="auto"
class="un-h-200px"
>
<div
v-for="item in data"
:key="item"
>
{{ item }}
</div>
</b-div>
</template>
IntersectionObserver
Scroll me down!
Hello world!
Scroll me down!
Hello world!
false
vue
<script setup lang="ts">
const root = ref(null);
const isVisible = ref(false);
function onIntersectionObserver([{ isIntersecting }]: IntersectionObserverEntry[]) {
isVisible.value = isIntersecting;
}
</script>
<template>
<b-div
overflow="auto"
class="un-h-200px"
>
<div>
<p class="un-h-200px">
Scroll me down!
</p>
<div
v-intersection-observer="onIntersectionObserver"
class="un-h-200px"
>
<p>Hello world!</p>
</div>
</div>
<!-- with options -->
<div ref="root">
<p class="un-h-500px">
Scroll me down!
</p>
<div
v-intersection-observer="[onIntersectionObserver, { root }]"
class="un-h-200px"
>
<p>Hello world!</p>
</div>
</div>
</b-div>
<div>{{ isVisible }}</div>
</template>
ResizeObserver
vue
<script setup lang="ts">
const text = ref('');
function onResizeObserver(entries) {
const [entry] = entries;
const { width, height } = entry.contentRect;
text.value = `width: ${width}, height: ${height}`;
}
</script>
<template>
<textarea v-resize-observer="onResizeObserver">
{{ text }}
</textarea>
</template>
Scroll
1
2
3
4
5
6
1
2
3
4
5
6
vue
<script setup lang="ts">
import type { UseScrollReturn } from '@vueuse/core';
const data = ref([1, 2, 3, 4, 5, 6]);
const state = ref();
function onScroll(scroll: UseScrollReturn) {
state.value = scroll; // {x, y, isScrolling, arrivedState, directions}
}
</script>
<template>
<b-div
v-scroll="onScroll"
overflow="auto"
class="un-h-100px"
>
<div
v-for="item in data"
:key="item"
>
{{ item }}
</div>
</b-div>
<!-- with options -->
<b-div
v-scroll="[onScroll, { throttle: 10 }]"
overflow="auto"
class="un-h-100px"
>
<div
v-for="item in data"
:key="item"
>
{{ item }}
</div>
</b-div>
<pre>{{ state }}</pre>
</template>