Vue
usePicker, Teleport, and two-way binding.
The adapter is a subpath of the same package. Nothing extra to install.
$ npm install loopem
<script setup>
import { usePicker } from 'loopem/vue'
const props = defineProps(['photos'])
const { container, slots, selectedItem } = usePicker({
items: () => props.photos,
layout: 'arc',
radius: 900,
})
</script>
<template>
<img :src="selectedItem?.full" alt="" />
<div class="picker" :ref="container">
<Teleport v-for="slot in slots" :key="slot.key" :to="slot.element">
<button class="thumb">
<img :src="photos[slot.index].thumb" alt="" />
</button>
</Teleport>
</div>
</template>items takes a MaybeRefOrGetter, so a ref or a getter both work and the track
follows the list. There is no update.
What you get back
container · slots · activeIndex · activeItem · selectedIndex ·
selectedItem · scrollTo · next · previous · select · seek ·
play · pause
Everything reactive is a ref or computed, so it works in a template
unwrapped.
Two-way binding
const chosen = ref(0)
const { container, slots } = usePicker({
items: () => props.dates,
selectedIndex: () => chosen.value,
onSelect: (index) => (chosen.value = index),
})Pass selectedIndex as a getter, not a plain number, or the track reads it once
at setup and stops following. onSelect fires from the picker’s own event rather
than from a watcher, which is what keeps it from reporting a stale index back
over the value you just set.
Working code: the Vue gallery.