Nuxt UI v3-alpha 已发布!

试用一下
组件

轮播

在可滚动区域中显示图像或内容。

用法

使用鼠标拖动、鼠标滚轮滚动或使用导航箭头进行导航。

将数组传递给 items 属性,并使用默认插槽显示每个项目的內容。

<script setup lang="ts">
const items = [
  'https://picsum.photos/600/800?random=1',
  'https://picsum.photos/600/800?random=2',
  'https://picsum.photos/600/800?random=3',
  'https://picsum.photos/600/800?random=4',
  'https://picsum.photos/600/800?random=5',
  'https://picsum.photos/600/800?random=6'
]
</script>

<template>
  <UCarousel v-slot="{ item }" :items="items">
    <img :src="item" width="300" height="400" draggable="false">
  </UCarousel>
</template>

吸附

轮播将吸附项目到中心 (snap-center)。您可以使用 snap 实用程序类通过 ui 属性更改此行为。

吸附到起点

<template>
  <UCarousel v-slot="{ item }" :items="items" :ui="{ item: 'snap-start' }">
    <img :src="item" width="200" height="300">
  </UCarousel>
</template>

吸附到终点

<template>
  <UCarousel v-slot="{ item }" :items="items" :ui="{ item: 'snap-end' }">
    <img :src="item" width="200" height="300">
  </UCarousel>
</template>
在 Tailwind CSS 文档中了解有关 scroll-snap-align 属性的更多信息。

大小

默认情况下,每个项目在轮播中将占用自己的大小。您可以使用 basis / width 实用程序类通过 ui 属性更改此行为。

<script setup lang="ts">
const items = [
  'https://picsum.photos/600/600?random=1',
  'https://picsum.photos/600/600?random=2',
  'https://picsum.photos/600/600?random=3',
  'https://picsum.photos/600/600?random=4',
  'https://picsum.photos/600/600?random=5',
  'https://picsum.photos/600/600?random=6'
]
</script>

<template>
  <UCarousel v-slot="{ item }" :items="items" :ui="{ item: 'basis-full md:basis-1/2 lg:basis-1/3' }">
    <img :src="item" class="w-full" draggable="false">
  </UCarousel>
</template>

在这个示例中,我们使用 basis-1/3 来一次显示 3 个项目,但您也可以使用它来使用 basis-full 使轮播全宽,并一次仅显示一个项目。

<script setup lang="ts">
const items = [
  'https://picsum.photos/1920/1080?random=1',
  'https://picsum.photos/1920/1080?random=2',
  'https://picsum.photos/1920/1080?random=3',
  'https://picsum.photos/1920/1080?random=4',
  'https://picsum.photos/1920/1080?random=5',
  'https://picsum.photos/1920/1080?random=6'
]
</script>

<template>
  <UCarousel v-slot="{ item }" :items="items" :ui="{ item: 'basis-full' }" class="rounded-lg overflow-hidden">
    <img :src="item" class="w-full" draggable="false">
  </UCarousel>
</template>

您还可以设置容器的宽度来居中轮播。

<script setup lang="ts">
const items = [
  'https://picsum.photos/600/800?random=1',
  'https://picsum.photos/600/800?random=2',
  'https://picsum.photos/600/800?random=3',
  'https://picsum.photos/600/800?random=4',
  'https://picsum.photos/600/800?random=5',
  'https://picsum.photos/600/800?random=6'
]
</script>

<template>
  <UCarousel v-slot="{ item }" :items="items" :ui="{ item: 'basis-full' }" class="w-64 mx-auto rounded-lg overflow-hidden">
    <img :src="item" class="w-full" draggable="false">
  </UCarousel>
</template>
在 Tailwind CSS 文档中了解有关 flex-basis 属性的更多信息。

箭头

使用 arrows 属性启用上一个和下一个按钮,当轮播到达第一个或最后一个项目时,它们将自动禁用。

<script setup lang="ts">
const items = [
  'https://picsum.photos/1920/1080?random=1',
  'https://picsum.photos/1920/1080?random=2',
  'https://picsum.photos/1920/1080?random=3',
  'https://picsum.photos/1920/1080?random=4',
  'https://picsum.photos/1920/1080?random=5',
  'https://picsum.photos/1920/1080?random=6'
]
</script>

<template>
  <UCarousel v-slot="{ item }" :items="items" :ui="{ item: 'basis-full' }" class="rounded-lg overflow-hidden" arrows>
    <img :src="item" class="w-full" draggable="false">
  </UCarousel>
</template>

您还可以使用 prev-buttonnext-button 属性自定义上一个和下一个按钮。

<script setup lang="ts">
const items = [
  'https://picsum.photos/600/800?random=1',
  'https://picsum.photos/600/800?random=2',
  'https://picsum.photos/600/800?random=3',
  'https://picsum.photos/600/800?random=4',
  'https://picsum.photos/600/800?random=5',
  'https://picsum.photos/600/800?random=6'
]
</script>

<template>
  <UCarousel
    v-slot="{ item }"
    :items="items"
    :ui="{
      item: 'basis-full',
      container: 'rounded-lg'
    }"
    :prev-button="{
      color: 'gray',
      icon: 'i-heroicons-arrow-left-20-solid',
      class: '-start-12'
    }"
    :next-button="{
      color: 'gray',
      icon: 'i-heroicons-arrow-right-20-solid',
      class: '-end-12'
    }"
    arrows
    class="w-64 mx-auto"
  >
    <img :src="item" class="w-full" draggable="false">
  </UCarousel>
</template>

在这个示例中,我们将按钮移到轮播容器之外。您也可以在 ui.carousel.default.prevButtonui.carousel.default.nextButton 中全局更改此设置。

指示器

使用 indicators 属性在轮播底部显示一个按钮列表,用于在项目之间导航。

<script setup lang="ts">
const items = [
  'https://picsum.photos/1920/1080?random=1',
  'https://picsum.photos/1920/1080?random=2',
  'https://picsum.photos/1920/1080?random=3',
  'https://picsum.photos/1920/1080?random=4',
  'https://picsum.photos/1920/1080?random=5',
  'https://picsum.photos/1920/1080?random=6'
]
</script>

<template>
  <UCarousel v-slot="{ item }" :items="items" :ui="{ item: 'basis-full' }" class="rounded-lg overflow-hidden" indicators>
    <img :src="item" class="w-full" draggable="false">
  </UCarousel>
</template>

指示器的数量将根据项目的数量自动生成。

<script setup lang="ts">
const items = [
  'https://picsum.photos/600/600?random=1',
  'https://picsum.photos/600/600?random=2',
  'https://picsum.photos/600/600?random=3',
  'https://picsum.photos/600/600?random=4',
  'https://picsum.photos/600/600?random=5',
  'https://picsum.photos/600/600?random=6'
]
</script>

<template>
  <UCarousel v-slot="{ item }" :items="items" :ui="{ item: 'basis-full md:basis-1/2 lg:basis-1/3' }" indicators class="rounded-lg overflow-hidden">
    <img :src="item" class="w-full" draggable="false">
  </UCarousel>
</template>

自动播放

您可以通过模板 ref 轻松地使用公开的 API 实现自动播放行为。

<script setup lang="ts">
const items = [
  'https://picsum.photos/1920/1080?random=1',
  'https://picsum.photos/1920/1080?random=2',
  'https://picsum.photos/1920/1080?random=3',
  'https://picsum.photos/1920/1080?random=4',
  'https://picsum.photos/1920/1080?random=5',
  'https://picsum.photos/1920/1080?random=6'
]

const carouselRef = ref()

onMounted(() => {
  setInterval(() => {
    if (!carouselRef.value) return

    if (carouselRef.value.page === carouselRef.value.pages) {
      return carouselRef.value.select(0)
    }

    carouselRef.value.next()
  }, 3000)
})
</script>

<template>
  <UCarousel
    ref="carouselRef"
    v-slot="{ item }"
    :items="items"
    :ui="{ item: 'basis-full' }"
    class="rounded-lg overflow-hidden"
    indicators
  >
    <img :src="item" class="w-full" draggable="false">
  </UCarousel>
</template>

插槽

默认

您可以在默认插槽中放入任何内容,而不仅仅是图像。您可以在插槽作用域中访问 itemindex 属性。

Sébastien Chopin

1. Sébastien Chopin

Pooya Parsa

2. Pooya Parsa

Daniel Roe

3. Daniel Roe

Anthony Fu

4. Anthony Fu

<script setup lang="ts">
const items = [{
  name: 'Sébastien Chopin',
  to: 'https://github.com/Atinux',
  avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/atinux' }
}, {
  name: 'Pooya Parsa',
  to: 'https://github.com/pi0',
  avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/pi0' }
}, {
  name: 'Daniel Roe',
  to: 'https://github.com/danielroe',
  avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/danielroe' }
}, {
  name: 'Anthony Fu',
  to: 'https://github.com/antfu',
  avatar: { src: 'https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/antfu' }
}]
</script>

<template>
  <UCarousel v-slot="{ item, index }" :items="items" :ui="{ item: 'w-full' }">
    <div class="text-center mx-auto">
      <img :src="item.avatar.src" :alt="item.name" class="rounded-full w-48 h-48 mb-2" draggable="false">

      <p class="font-semibold">
        {{ index + 1 }}. {{ item.name }}
      </p>
    </div>
  </UCarousel>
</template>

prev / next

启用 arrows 属性后,使用 #prev#next 插槽设置上一个和下一个按钮的內容。您可以在插槽作用域中访问 disabled 属性和 on-click 方法。

<script setup lang="ts">
const items = [
  'https://picsum.photos/600/800?random=1',
  'https://picsum.photos/600/800?random=2',
  'https://picsum.photos/600/800?random=3',
  'https://picsum.photos/600/800?random=4',
  'https://picsum.photos/600/800?random=5',
  'https://picsum.photos/600/800?random=6'
]
</script>

<template>
  <UCarousel
    :items="items"
    :ui="{
      item: 'basis-full',
      container: 'rounded-lg'
    }"
    arrows
    class="w-64 mx-auto"
  >
    <template #default="{ item }">
      <img :src="item" class="w-full" draggable="false">
    </template>

    <template #prev="{ onClick, disabled }">
      <button :disabled="disabled" @click="onClick">
        Prev
      </button>
    </template>

    <template #next="{ onClick, disabled }">
      <button :disabled="disabled" @click="onClick">
        Next
      </button>
    </template>
  </UCarousel>
</template>
您可以通过 ui.arrows.wrapper 自定义按钮的位置。

指示器

启用 indicators 属性后,使用 #indicator 插槽设置指示器的內容。您可以在插槽作用域中访问 activepage 属性和 on-click 方法。

<script setup lang="ts">
const items = [
  'https://picsum.photos/600/800?random=1',
  'https://picsum.photos/600/800?random=2',
  'https://picsum.photos/600/800?random=3',
  'https://picsum.photos/600/800?random=4',
  'https://picsum.photos/600/800?random=5',
  'https://picsum.photos/600/800?random=6'
]
</script>

<template>
  <UCarousel
    :items="items"
    :ui="{
      item: 'basis-full',
      container: 'rounded-lg',
      indicators: {
        wrapper: 'relative bottom-0 mt-4'
      }
    }"
    indicators
    class="w-64 mx-auto"
  >
    <template #default="{ item }">
      <img :src="item" class="w-full" draggable="false">
    </template>

    <template #indicator="{ onClick, page, active }">
      <UButton :label="String(page)" :variant="active ? 'solid' : 'outline'" size="2xs" class="rounded-full min-w-6 justify-center" @click="onClick(page)" />
    </template>
  </UCarousel>
</template>
您可以通过 ui.indicators.wrapper 自定义按钮的位置。

属性

ui
DeepPartial<{ wrapper: string; container: string; item: string; arrows: { wrapper: string; }; indicators: { wrapper: string; base: string; active: string; inactive: string; }; default: { prevButton: { color: "black"; class: string; icon: string; }; nextButton: { ...; }; }; } & { ...; }>
undefined
items
any[]
[]
dir
"ltr" | "rtl"
"ltr"
prevButton
Button & { class?: string; }
config.default.prevButton as Button & { class?: string; }
nextButton
Button & { class?: string; }
config.default.nextButton as Button & { class?: string; }
arrows
boolean
false
indicators
boolean
false

API

通过模板 ref 访问组件时,您可以使用以下方法:

page
number

当前页面。

pages
number

总页面数。

select (page)

转到特定页面。

next ()

转到下一页。

prev ()

转到上一页。

配置

{
  wrapper: 'relative',
  container: 'relative w-full flex overflow-x-auto snap-x snap-mandatory scroll-smooth',
  item: 'flex flex-none snap-center',
  arrows: {
    wrapper: 'flex items-center justify-between'
  },
  indicators: {
    wrapper: 'absolute flex items-center justify-center gap-3 bottom-4 inset-x-0',
    base: 'rounded-full h-3 w-3',
    active: 'bg-primary-500 dark:bg-primary-400',
    inactive: 'bg-gray-100 dark:bg-gray-800'
  },
  default: {
    prevButton: {
      color: 'black',
      class: 'rtl:[&_span:first-child]:rotate-180 absolute start-4 top-1/2 transform -translate-y-1/2 rounded-full',
      icon: 'i-heroicons-chevron-left-20-solid'
    },
    nextButton: {
      color: 'black',
      class: 'rtl:[&_span:last-child]:rotate-180 absolute end-4 top-1/2 transform -translate-y-1/2 rounded-full',
      icon: 'i-heroicons-chevron-right-20-solid'
    }
  }
}