使用法
カルーセルコンポーネントを使用して、カルーセル内のアイテムのリストを表示します。
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6'
]
</script>
<template>
<UCarousel
v-slot="{ item }"
loop
arrows
:autoplay="{ delay: 2000 }"
wheel-gestures
:prev="{ variant: 'solid' }"
:next="{ variant: 'solid' }"
:items="items"
:ui="{
item: 'basis-1/3 ps-0',
prev: 'sm:start-8',
next: 'sm:end-8',
container: 'ms-0'
}"
>
<img :src="item" width="320" height="320">
</UCarousel>
</template>
アイテム
itemsプロパティを配列として使用し、デフォルトスロットを使用して各アイテムをレンダリングします。
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6'
]
</script>
<template>
<UCarousel v-slot="{ item }" :items="items" class="w-full max-w-xs mx-auto">
<img :src="item" width="320" height="320" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
次のプロパティを持つオブジェクトの配列を渡すこともできます:
class?: anyui?: { item?: ClassNameValue }
表示する項目の数を制御するには、basis/widthユーティリティクラスを使用します。
<script setup lang="ts">
const items = [
'https://picsum.photos/468/468?random=1',
'https://picsum.photos/468/468?random=2',
'https://picsum.photos/468/468?random=3',
'https://picsum.photos/468/468?random=4',
'https://picsum.photos/468/468?random=5',
'https://picsum.photos/468/468?random=6'
]
</script>
<template>
<UCarousel v-slot="{ item }" :items="items" :ui="{ item: 'basis-1/3' }">
<img :src="item" width="234" height="234" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
Orientation
orientationプロパティを使用してプログレスの向きを変更します。デフォルトはhorizontalです。
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6'
]
</script>
<template>
<UCarousel
v-slot="{ item }"
orientation="vertical"
:items="items"
:ui="{ container: 'h-[336px]' }"
class="w-full max-w-xs mx-auto"
>
<img :src="item" width="320" height="320" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
heightを指定する必要があります。矢印
arrowsプロパティを使用してprevとnextボタンを表示します。
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6'
]
</script>
<template>
<UCarousel v-slot="{ item }" arrows :items="items" class="w-full max-w-xs mx-auto">
<img :src="item" width="320" height="320" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
前/次へ
prevとnextのプロップを使用して、Buttonのプロップで前ボタンと次ボタンをカスタマイズします。
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6'
]
</script>
<template>
<UCarousel
v-slot="{ item }"
arrows
:prev="{ color: 'primary' }"
:next="{ variant: 'solid' }"
:items="items"
class="w-full max-w-xs mx-auto"
>
<img :src="item" width="320" height="320" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
Prev/Nextアイコン
prev-iconとnext-iconプロップを使用して、ボタンIconをカスタマイズします。デフォルトはi-lucide-arrow-left/i-lucide-arrow-rightです。
<script setup lang="ts">
defineProps<{
prevIcon?: string
nextIcon?: string
}>()
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6'
]
</script>
<template>
<UCarousel
v-slot="{ item }"
arrows
:prev-icon="prevIcon"
:next-icon="nextIcon"
:items="items"
class="w-full max-w-xs mx-auto"
>
<img :src="item" width="320" height="320" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
Dots
dotsプロパティを使用して、特定のスライドまでスクロールするドットのリストを表示します。
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6'
]
</script>
<template>
<UCarousel v-slot="{ item }" dots :items="items" class="w-full max-w-xs mx-auto">
<img :src="item" width="320" height="320" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
ドットの数は、ビューに表示されるスライドの数に基づいています。
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6'
]
</script>
<template>
<UCarousel v-slot="{ item }" dots :items="items" :ui="{ item: 'basis-1/3' }">
<img :src="item" width="320" height="320" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
プラグイン
カルーセルコンポーネントは公式のEmblaカルーセルプラグインを実装しています。
自動再生
このプラグインは、エンブラカルーセルをautoplay機能で拡張するために使用します。
autoplayプロパティをブール値またはオブジェクトとして使用して、Autoplayプラグインを設定します。
<script setup lang="ts">
const items = [
'https://picsum.photos/468/468?random=1',
'https://picsum.photos/468/468?random=2',
'https://picsum.photos/468/468?random=3',
'https://picsum.photos/468/468?random=4',
'https://picsum.photos/468/468?random=5',
'https://picsum.photos/468/468?random=6'
]
</script>
<template>
<UCarousel
v-slot="{ item }"
loop
arrows
dots
:autoplay="{ delay: 2000 }"
:items="items"
:ui="{ item: 'basis-1/3' }"
>
<img :src="item" width="234" height="234" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
loopプロパティを使用しています。Autoスクロール
このプラグインはEmbla Carouselをauto scroll機能で拡張するために使用します。
auto-scrollプロパティをブール値またはオブジェクトとして使用して、Auto Scrollプラグインを設定します。
<script setup lang="ts">
const items = [
'https://picsum.photos/468/468?random=1',
'https://picsum.photos/468/468?random=2',
'https://picsum.photos/468/468?random=3',
'https://picsum.photos/468/468?random=4',
'https://picsum.photos/468/468?random=5',
'https://picsum.photos/468/468?random=6'
]
</script>
<template>
<UCarousel
v-slot="{ item }"
loop
dots
arrows
auto-scroll
:items="items"
:ui="{ item: 'basis-1/3' }"
>
<img :src="item" width="234" height="234" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
loopプロパティを使用しています。Auto高さ
このプラグインは、エンブラカルーセルをauto height機能で拡張するために使用します。ビュー内の最も高いスライドの高さに合わせてカルーセルコンテナの高さを変更します。
auto-heightプロパティをブール値またはオブジェクトとして使用して、Auto Heightプラグインを設定します。
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/320?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/320?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/320?random=6'
]
</script>
<template>
<UCarousel
v-slot="{ item }"
auto-height
arrows
dots
:items="items"
:ui="{
container: 'transition-[height]',
controls: 'absolute -top-8 inset-x-12',
dots: '-top-7',
dot: 'w-6 h-1'
}"
class="w-full max-w-xs mx-auto"
>
<img :src="item" width="320" height="320" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
transition-[height]クラスを追加して高さの変更をアニメーション化しています。クラス名
Class Namesは、Embla Carousel用の** class name toggle**ユーティリティプラグインで、カルーセル上のクラス名の切り替えを自動化できます。
class-namesプロパティをブール値またはオブジェクトとして使用して、クラス名pluginを設定します。
<script setup lang="ts">
const items = [
'https://picsum.photos/528/528?random=1',
'https://picsum.photos/528/528?random=2',
'https://picsum.photos/528/528?random=3',
'https://picsum.photos/528/528?random=4',
'https://picsum.photos/528/528?random=5',
'https://picsum.photos/528/528?random=6'
]
</script>
<template>
<UCarousel
v-slot="{ item }"
class-names
arrows
:items="items"
:ui="{
item: 'basis-[70%] transition-opacity [&:not(.is-snapped)]:opacity-10'
}"
class="mx-auto max-w-sm"
>
<img :src="item" width="264" height="264" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
itemにtransition-opacity [&:not(.is-snapped)]:opacity-10クラスを追加しています。フェード
このプラグインは、Emblaのカルーセルスクロール機能をfade transitionsに置き換えるために使用されます。
fadeプロパティをブール値またはオブジェクトとして使用して、Fadeプラグインを設定します。
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6'
]
</script>
<template>
<UCarousel
v-slot="{ item }"
fade
arrows
dots
:items="items"
class="w-full max-w-xs mx-auto"
>
<img :src="item" width="320" height="320" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
Wheelジェスチャー
このプラグインはEmblaカルーセルを拡張し、マウス/トラックパッドホイール**を使用してカルーセルをナビゲートする機能を追加します。
wheel-gesturesプロパティをブール値またはオブジェクトとして使用して、Wheel Gesturesプラグインを設定します。
<script setup lang="ts">
const items = [
'https://picsum.photos/468/468?random=1',
'https://picsum.photos/468/468?random=2',
'https://picsum.photos/468/468?random=3',
'https://picsum.photos/468/468?random=4',
'https://picsum.photos/468/468?random=5',
'https://picsum.photos/468/468?random=6'
]
</script>
<template>
<UCarousel
v-slot="{ item }"
loop
wheel-gestures
:items="items"
:ui="{ item: 'basis-1/3' }"
>
<img :src="item" width="234" height="234" class="rounded-lg" loading="lazy">
</UCarousel>
</template>
例
サムネイル付き
emblaApiのscrollToメソッドを使用して、特定のスライドに移動するカルーセルの下にサムネイルを表示できます。
<script setup lang="ts">
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6'
]
const carousel = useTemplateRef('carousel')
const activeIndex = ref(0)
function onClickPrev() {
activeIndex.value--
}
function onClickNext() {
activeIndex.value++
}
function onSelect(index: number) {
activeIndex.value = index
}
function select(index: number) {
activeIndex.value = index
carousel.value?.emblaApi?.scrollTo(index)
}
</script>
<template>
<div class="flex-1 w-full">
<UCarousel
ref="carousel"
v-slot="{ item }"
arrows
:items="items"
:prev="{ onClick: onClickPrev }"
:next="{ onClick: onClickNext }"
class="w-full max-w-xs mx-auto"
@select="onSelect"
>
<img :src="item" width="320" height="320" class="rounded-lg" loading="lazy">
</UCarousel>
<div class="flex gap-1 justify-between pt-4 max-w-xs mx-auto">
<div
v-for="(item, index) in items"
:key="index"
class="size-11 opacity-25 hover:opacity-100 transition-opacity"
:class="{ 'opacity-100': activeIndex === index }"
@click="select(index)"
>
<img :src="item" width="44" height="44" class="rounded-lg" loading="lazy">
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, useTemplateRef } from 'vue'
const items = [
'https://picsum.photos/640/640?random=1',
'https://picsum.photos/640/640?random=2',
'https://picsum.photos/640/640?random=3',
'https://picsum.photos/640/640?random=4',
'https://picsum.photos/640/640?random=5',
'https://picsum.photos/640/640?random=6'
]
const carousel = useTemplateRef('carousel')
const activeIndex = ref(0)
function onClickPrev() {
activeIndex.value--
}
function onClickNext() {
activeIndex.value++
}
function onSelect(index: number) {
activeIndex.value = index
}
function select(index: number) {
activeIndex.value = index
carousel.value?.emblaApi?.scrollTo(index)
}
</script>
<template>
<div class="flex-1 w-full">
<UCarousel
ref="carousel"
v-slot="{ item }"
arrows
:items="items"
:prev="{ onClick: onClickPrev }"
:next="{ onClick: onClickNext }"
class="w-full max-w-xs mx-auto"
@select="onSelect"
>
<img :src="item" width="320" height="320" class="rounded-lg" loading="lazy">
</UCarousel>
<div class="flex gap-1 justify-between pt-4 max-w-xs mx-auto">
<div
v-for="(item, index) in items"
:key="index"
class="size-11 opacity-25 hover:opacity-100 transition-opacity"
:class="{ 'opacity-100': activeIndex === index }"
@click="select(index)"
>
<img :src="item" width="44" height="44" class="rounded-lg" loading="lazy">
</div>
</div>
</div>
</template>
API
Props
| Prop | Default | Type |
|---|---|---|
as | 'div' | anyThe element or component this component should render as. |
prev | { size: 'md', color: 'neutral', variant: 'link' } | Omit<ButtonProps, LinkPropsKeys>Configure the prev button when arrows are enabled. |
prevIcon | appConfig.ui.icons.arrowLeft | anyThe icon displayed in the prev button. |
next | { size: 'md', color: 'neutral', variant: 'link' } | Omit<ButtonProps, LinkPropsKeys>Configure the next button when arrows are enabled. |
nextIcon | appConfig.ui.icons.arrowRight | anyThe icon displayed in the next button. |
arrows | false | boolean Display prev and next buttons to scroll the carousel. |
dots | false | boolean Display dots to scroll to a specific slide. |
orientation | 'horizontal' | "vertical" | "horizontal"The orientation of the carousel. |
items | T[] | |
autoplay | false | boolean | Partial<CreateOptionsType<OptionsType>> Enable Autoplay plugin |
autoScroll | false | boolean | Partial<CreateOptionsType<OptionsType>> Enable Auto Scroll plugin |
autoHeight | false | boolean | Partial<CreateOptionsType<{ active: boolean; breakpoints: { [key: string]: Omit<Partial<any>, "breakpoints">; }; }>> Enable Auto Height plugin |
classNames | false | boolean | Partial<CreateOptionsType<OptionsType>> Enable Class Names plugin |
fade | false | boolean | Partial<CreateOptionsType<{ active: boolean; breakpoints: { [key: string]: Omit<Partial<any>, "breakpoints">; }; }>> Enable Fade plugin |
wheelGestures | false | boolean | WheelGesturesPluginOptions Enable Wheel Gestures plugin |
align | 'center' | "start" | "center" | "end" | (viewSize: number, snapSize: number, index: number): number |
containScroll | 'trimSnaps' | false | "trimSnaps" | "keepSnaps" |
slidesToScroll | 1 | number | "auto" |
dragFree | false | boolean |
dragThreshold | 10 | number |
inViewThreshold | 0 | number | number[] |
loop | false | boolean |
skipSnaps | false | boolean |
duration | 25 | number |
startIndex | 0 | number |
watchDrag | true | false | true | (emblaApi: EmblaCarouselType, evt: PointerEventType): boolean | void |
watchResize | true | false | true | (emblaApi: EmblaCarouselType, entries: ResizeObserverEntry[]): boolean | void |
watchSlides | true | false | true | (emblaApi: EmblaCarouselType, mutations: MutationRecord[]): boolean | void |
watchFocus | true | false | true | (emblaApi: EmblaCarouselType, evt: FocusEvent): boolean | void |
active | true | boolean |
breakpoints | {} | { [key: string]: Omit<Partial<CreateOptionsType<{ align: AlignmentOptionType; axis: AxisOptionType; container: string | HTMLElement | null; slides: string | HTMLElement[] | NodeListOf<HTMLElement> | null; containScroll: ScrollContainOptionType; direction: AxisDirectionOptionType; slidesToScroll: SlidesToScrollOptionType; dragFree: boolean; dragThreshold: number; inViewThreshold: number | number[] | undefined; loop: boolean; skipSnaps: boolean; duration: number; startIndex: number; watchDrag: DragHandlerOptionType; watchResize: ResizeHandlerOptionType; watchSlides: SlidesHandlerOptionType; watchFocus: FocusHandlerOptionType; }>>, "breakpoints">; } |
ui | { root?: SlotClass; viewport?: SlotClass; container?: SlotClass; item?: SlotClass; controls?: SlotClass; arrows?: SlotClass; prev?: SlotClass; next?: SlotClass; dots?: SlotClass; dot?: SlotClass; } |
スロット
| Slot | Type |
|---|---|
default | { item: T; index: number; } |
Emits
| Event | Type |
|---|---|
select | [selectedIndex: number] |
Expose
useTemplateRefを使用して型付きコンポーネントインスタンスにアクセスできます。
<script setup lang="ts">
const carousel = useTemplateRef('carousel')
</script>
<template>
<UCarousel ref="carousel" />
</template>
これにより、以下にアクセスできます:
| 名前 | タイプ |
|---|---|
emblaRef | Ref<HTMLElement | null> |
emblaApi | Ref<EmblaCarouselType | null> |
Theme
export default defineAppConfig({
ui: {
carousel: {
slots: {
root: 'relative focus:outline-none',
viewport: 'overflow-hidden',
container: 'flex items-start',
item: 'min-w-0 shrink-0 basis-full',
controls: '',
arrows: '',
prev: 'absolute rounded-full',
next: 'absolute rounded-full',
dots: 'absolute inset-x-0 -bottom-7 flex flex-wrap items-center justify-center gap-3',
dot: [
'cursor-pointer size-3 bg-accented rounded-full outline-inverted/25 focus-visible:outline-3',
'transition'
]
},
variants: {
orientation: {
vertical: {
container: 'flex-col -mt-4',
item: 'pt-4',
prev: 'top-4 sm:-top-12 left-1/2 -translate-x-1/2 rotate-90 rtl:-rotate-90',
next: 'bottom-4 sm:-bottom-12 left-1/2 -translate-x-1/2 rotate-90 rtl:-rotate-90'
},
horizontal: {
container: 'flex-row -ms-4',
item: 'ps-4',
prev: 'start-4 sm:-start-12 top-1/2 -translate-y-1/2',
next: 'end-4 sm:-end-12 top-1/2 -translate-y-1/2'
}
},
active: {
true: {
dot: 'data-[state=active]:bg-inverted'
}
}
}
}
}
})import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
carousel: {
slots: {
root: 'relative focus:outline-none',
viewport: 'overflow-hidden',
container: 'flex items-start',
item: 'min-w-0 shrink-0 basis-full',
controls: '',
arrows: '',
prev: 'absolute rounded-full',
next: 'absolute rounded-full',
dots: 'absolute inset-x-0 -bottom-7 flex flex-wrap items-center justify-center gap-3',
dot: [
'cursor-pointer size-3 bg-accented rounded-full outline-inverted/25 focus-visible:outline-3',
'transition'
]
},
variants: {
orientation: {
vertical: {
container: 'flex-col -mt-4',
item: 'pt-4',
prev: 'top-4 sm:-top-12 left-1/2 -translate-x-1/2 rotate-90 rtl:-rotate-90',
next: 'bottom-4 sm:-bottom-12 left-1/2 -translate-x-1/2 rotate-90 rtl:-rotate-90'
},
horizontal: {
container: 'flex-row -ms-4',
item: 'ps-4',
prev: 'start-4 sm:-start-12 top-1/2 -translate-y-1/2',
next: 'end-4 sm:-end-12 top-1/2 -translate-y-1/2'
}
},
active: {
true: {
dot: 'data-[state=active]:bg-inverted'
}
}
}
}
}
})
]
})