Nuxt UI v3-alpha 已发布!

试用一下
组件

下拉菜单

在下拉菜单中显示操作列表。

用法

将一个二维数组传递给下拉菜单组件的 items 属性。每个二维数组代表一组项目。每个项目可以具有以下属性

  • label - 项目的标签。
  • labelClass - 项目标签的类名。
  • icon - 项目的图标。
  • iconClass - 项目图标的类名。
  • avatar - 项目的头像。您可以传递 头像 组件的所有属性。
  • shortcuts - 项目的快捷键。
  • slot - 项目的插槽。
  • disabled - 项目是否禁用。
  • class - 项目的类名。
  • click - 项目的点击处理程序。

您还可以传递来自 NuxtLink 组件的任何属性,例如 toexact 等。

<script setup lang="ts">
const items = [
  [{
    label: 'Profile',
    avatar: {
      src: 'https://avatars.githubusercontent.com/u/739984?v=4'
    }
  }], [{
    label: 'Edit',
    icon: 'i-heroicons-pencil-square-20-solid',
    shortcuts: ['E'],
    click: () => {
      console.log('Edit')
    }
  }, {
    label: 'Duplicate',
    icon: 'i-heroicons-document-duplicate-20-solid',
    shortcuts: ['D'],
    disabled: true
  }], [{
    label: 'Archive',
    icon: 'i-heroicons-archive-box-20-solid'
  }, {
    label: 'Move',
    icon: 'i-heroicons-arrow-right-circle-20-solid'
  }], [{
    label: 'Delete',
    icon: 'i-heroicons-trash-20-solid',
    shortcuts: ['', 'D']
  }]
]
</script>

<template>
  <UDropdown :items="items" :popper="{ placement: 'bottom-start' }">
    <UButton color="white" label="Options" trailing-icon="i-heroicons-chevron-down-20-solid" />
  </UDropdown>
</template>

模式

使用 mode 属性在 clickhover 模式之间切换。

<script setup lang="ts">
const items = [
  [{
    label: 'Profile',
    avatar: {
      src: 'https://avatars.githubusercontent.com/u/739984?v=4'
    }
  }]
]
</script>

<template>
  <UDropdown :items="items" mode="hover" :popper="{ placement: 'bottom-start' }">
    <UButton color="white" label="Options" trailing-icon="i-heroicons-chevron-down-20-solid" />
  </UDropdown>
</template>

手动

使用 v-model:open 手动控制状态。在本例中,按下 O 切换下拉菜单。

<script setup lang="ts">
const items = [
  [{
    label: 'Profile',
    avatar: {
      src: 'https://avatars.githubusercontent.com/u/739984?v=4'
    }
  }]
]

const open = ref(true)

defineShortcuts({
  o: () => open.value = !open.value
})
</script>

<template>
  <UDropdown v-model:open="open" :items="items" :popper="{ placement: 'bottom-start' }">
    <UButton color="white" label="Options" trailing-icon="i-heroicons-chevron-down-20-solid" />
  </UDropdown>
</template>

弹出框

使用 popper 属性自定义弹出框实例。

箭头

<script setup lang="ts">
const items = [
  [{
    label: 'Profile',
    avatar: {
      src: 'https://avatars.githubusercontent.com/u/739984?v=4'
    }
  }]
]
</script>

<template>
  <UDropdown :items="items" :popper="{ arrow: true }">
    <UButton color="white" label="Options" trailing-icon="i-heroicons-chevron-down-20-solid" />
  </UDropdown>
</template>

位置

<script setup lang="ts">
const items = [
  [{
    label: 'Profile',
    avatar: {
      src: 'https://avatars.githubusercontent.com/u/739984?v=4'
    }
  }]
]
</script>

<template>
  <UDropdown :items="items" :popper="{ placement: 'right-start' }">
    <UButton color="white" label="Options" trailing-icon="i-heroicons-chevron-down-20-solid" />
  </UDropdown>
</template>

偏移量

<script setup lang="ts">
const items = [
  [{
    label: 'Profile',
    avatar: {
      src: 'https://avatars.githubusercontent.com/u/739984?v=4'
    }
  }]
]
</script>

<template>
  <UDropdown :items="items" :popper="{ offsetDistance: 0, placement: 'right-start' }">
    <UButton color="white" label="Options" trailing-icon="i-heroicons-chevron-down-20-solid" />
  </UDropdown>
</template>

插槽

项目

使用 #item 插槽自定义项目内容,或传递 slot 属性自定义特定项目。您将在插槽作用域中访问到 item 属性。

<script setup lang="ts">
const items = [
  [{
    label: '[email protected]',
    slot: 'account',
    disabled: true
  }], [{
    label: 'Settings',
    icon: 'i-heroicons-cog-8-tooth'
  }], [{
    label: 'Documentation',
    icon: 'i-heroicons-book-open'
  }, {
    label: 'Changelog',
    icon: 'i-heroicons-megaphone'
  }, {
    label: 'Status',
    icon: 'i-heroicons-signal'
  }], [{
    label: 'Sign out',
    icon: 'i-heroicons-arrow-left-on-rectangle'
  }]
]
</script>

<template>
  <UDropdown :items="items" :ui="{ item: { disabled: 'cursor-text select-text' } }" :popper="{ placement: 'bottom-start' }">
    <UAvatar src="https://avatars.githubusercontent.com/u/739984?v=4" />

    <template #account="{ item }">
      <div class="text-left">
        <p>
          Signed in as
        </p>
        <p class="truncate font-medium text-gray-900 dark:text-white">
          {{ item.label }}
        </p>
      </div>
    </template>

    <template #item="{ item }">
      <span class="truncate">{{ item.label }}</span>

      <UIcon :name="item.icon" class="flex-shrink-0 h-4 w-4 text-gray-400 dark:text-gray-500 ms-auto" />
    </template>
  </UDropdown>
</template>

属性

ui
{ wrapper?: string; container?: string; trigger?: string; width?: string; height?: string; background?: string; shadow?: string; rounded?: string; ring?: string; base?: string; divide?: string; padding?: string; ... 4 more ...; arrow?: DeepPartial<...>; } & { ...; } & { ...; }
{}
模式
"click" | "hover"
"click"
项目
DropdownItem[][]
[]
弹出框
PopperOptions
{}
打开延迟
number
config.default.openDelay
关闭延迟
number
config.default.closeDelay
禁用
boolean
false
打开
boolean
undefined

配置

{
  wrapper: 'relative inline-flex text-left rtl:text-right',
  container: 'z-20 group',
  trigger: 'inline-flex w-full',
  width: 'w-48',
  height: '',
  background: 'bg-white dark:bg-gray-800',
  shadow: 'shadow-lg',
  rounded: 'rounded-md',
  ring: 'ring-1 ring-gray-200 dark:ring-gray-700',
  base: 'relative focus:outline-none overflow-y-auto scroll-py-1',
  divide: 'divide-y divide-gray-200 dark:divide-gray-700',
  padding: 'p-1',
  item: {
    base: 'group flex items-center gap-1.5 w-full',
    rounded: 'rounded-md',
    padding: 'px-1.5 py-1.5',
    size: 'text-sm',
    active: 'bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-white',
    inactive: 'text-gray-700 dark:text-gray-200',
    disabled: 'cursor-not-allowed opacity-50',
    icon: {
      base: 'flex-shrink-0 w-5 h-5',
      active: 'text-gray-500 dark:text-gray-400',
      inactive: 'text-gray-400 dark:text-gray-500'
    },
    avatar: {
      base: 'flex-shrink-0',
      size: '2xs'
    },
    label: 'truncate',
    shortcuts: 'hidden md:inline-flex flex-shrink-0 gap-0.5 ms-auto'
  },
  transition: {
    enterActiveClass: 'transition duration-100 ease-out',
    enterFromClass: 'transform scale-95 opacity-0',
    enterToClass: 'transform scale-100 opacity-100',
    leaveActiveClass: 'transition duration-75 ease-in',
    leaveFromClass: 'transform scale-100 opacity-100',
    leaveToClass: 'transform scale-95 opacity-0'
  },
  popper: {
    placement: 'bottom-end',
    strategy: 'fixed'
  },
  default: {
    openDelay: 0,
    closeDelay: 0
  },
  arrow: {
    base: 'invisible before:visible before:block before:rotate-45 before:z-[-1] before:w-2 before:h-2',
    ring: 'before:ring-1 before:ring-gray-200 dark:before:ring-gray-700',
    rounded: 'before:rounded-sm',
    background: 'before:bg-white dark:before:bg-gray-700',
    shadow: 'before:shadow',
    placement: "group-data-[popper-placement*='right']:-left-1 group-data-[popper-placement*='left']:-right-1 group-data-[popper-placement*='top']:-bottom-1 group-data-[popper-placement*='bottom']:-top-1"
  }
}