Nuxt UI v3-alpha 已发布!

试用

仪表盘侧边栏链接

一个可折叠和可拖动的链接列表,用于在仪表盘侧边栏中显示。

用法

将链接树及其子级传递给 DashboardSidebarLinks 组件的 links 属性。

每个链接都可以有一个 labeliconavatarchipbadgetooltip 等。(有关更多详细信息,请参阅 props 部分)。您还可以传递来自 NuxtLink 组件的任何属性,例如 totargetexact 等。

<script setup lang="ts">
const links = [{
  label: 'Home',
  icon: 'i-heroicons-home',
  tooltip: {
    text: 'Home',
    shortcuts: ['G', 'H']
  }
}, {
  label: 'Inbox',
  icon: 'i-heroicons-inbox',
  badge: '4',
  tooltip: {
    text: 'Inbox',
    shortcuts: ['G', 'I']
  }
}, {
  label: 'Users',
  icon: 'i-heroicons-user-group',
  tooltip: {
    text: 'Users',
    shortcuts: ['G', 'U']
  }
}, {
  label: 'Settings',
  icon: 'i-heroicons-cog-8-tooth',
  children: [{
    label: 'General'
  }, {
    label: 'Members'
  }, {
    label: 'Notifications'
  }],
  tooltip: {
    text: 'Settings',
    shortcuts: ['G', 'S']
  }
}]
</script>

<template>
  <UDashboardSidebarLinks :links="links" />
</template>
子级在没有图标、头像或芯片的情况下具有特定的样式,带有一个点和边框。

可折叠

您可以使用 collapsible 属性(默认为 true)来阻止具有子级的链接折叠。

<script setup lang="ts">
const links = [{
  label: 'Settings',
  icon: 'i-heroicons-cog-8-tooth',
  collapsible: false,
  children: [{
    label: 'General'
  }, {
    label: 'Members'
  }, {
    label: 'Notifications'
  }]
}]
</script>

<template>
  <UDashboardSidebarLinks :links="links" />
</template>

默认打开

您可以使用 defaultOpen 属性(默认为 true)使可折叠链接(带子级)默认打开。

如果您想根据当前路由控制打开状态,这将非常有用。

<script setup lang="ts">
const route = useRoute()

const links = computed(() => [{
  label: 'Settings',
  icon: 'i-heroicons-cog-8-tooth',
  defaultOpen: route.path.startsWith('/settings'),
  children: [{
    label: 'General'
  }, {
    label: 'Members'
  }, {
    label: 'Notifications'
  }]
}])
</script>

<template>
  <UDashboardSidebarLinks :links="links" />
</template>

可拖动

您可以使用 draggable 属性使子级可拖动。您需要监听 @update:links 事件来更新您的链接。

<script setup lang="ts">
const colors = ref(['green', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet'].map(color => ({ label: color, chip: color })))

const links = computed(() => [{
  label: 'Favorites',
  draggable: true,
  children: colors.value
}])
</script>

<template>
  <UDashboardSidebarLinks :links="links" @update:links="links => colors = links" />
</template>

您可以在 DashboardSidebar 组件中使用多个 DashboardSidebarLinks 组件实例来创建不同的部分。

layouts/default.vue
<template>
  <UDashboardLayout>
    <UDashboardPanel>
      <UDashboardNavbar />

      <UDashboardSidebar>
        <UDashboardSidebarLinks />

        <UDivider />

        <UDashboardSidebarLinks />

        <div class="flex-1" />

        <UDashboardSidebarLinks />

        <UDivider class="sticky bottom-0" />
      </UDashboardSidebar>
    </UDashboardPanel>

    <slot />
  </UDashboardLayout>
</template>

插槽

icon
{ link: DashboardSidebarLink; isActive: any; }
default
{ link: DashboardSidebarLink; isActive: any; }
badge
{ link: DashboardSidebarLink; isActive: any; }

属性

ui
any
{}
links
DashboardSidebarLink[]
[]
level
number
0
draggable
boolean
false

配置

{
  wrapper: 'relative !min-h-[auto] !min-w-[auto]',
  container: '!overflow-visible',
  base: 'group relative flex items-center gap-1.5 px-2.5 py-1.5 w-full rounded-md font-medium text-sm focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-2 focus-visible:before:ring-primary-500 dark:focus-visible:before:ring-primary-400 before:absolute before:inset-px before:rounded-md disabled:cursor-not-allowed disabled:opacity-75',
  active: 'text-gray-900 dark:text-white before:bg-gray-100 dark:before:bg-gray-800',
  inactive: 'text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:before:bg-gray-50 dark:hover:before:bg-gray-800/50',
  icon: {
    base: 'flex-shrink-0 w-5 h-5 relative',
    active: 'text-gray-900 dark:text-white',
    inactive: 'text-gray-400 dark:text-gray-500 group-hover:text-gray-700 dark:group-hover:text-gray-200'
  },
  trailingIcon: {
    name: i-heroicons-chevron-down-20-solid,
    base: 'ml-auto w-5 h-5 transform transition-transform duration-200 flex-shrink-0',
    active: '',
    inactive: '-rotate-90'
  },
  avatar: {
    base: 'flex-shrink-0',
    size: '2xs'
  },
  chip: {
    base: 'flex-shrink-0 mx-2.5',
    size: 'sm'
  },
  badge: {
    base: 'flex-shrink-0 ml-auto relative rounded',
    color: 'gray',
    variant: 'solid',
    size: 'xs'
  },
  label: 'text-sm truncate relative',
  dot: {
    wrapper: 'w-px h-full mx-[9.5px] bg-gray-200 dark:bg-gray-700 relative',
    after: 'after:absolute after:z-[1] after:w-px after:h-full after:bg-gray-200 after:dark:bg-gray-700 after:transform after:translate-y-full',
    base: 'w-1 h-1 rounded-full absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2',
    active: 'bg-gray-900 dark:bg-white',
    inactive: 'bg-gray-400 dark:bg-gray-500 group-hover:bg-gray-700 dark:group-hover:bg-gray-200'
  },
  tooltip: {
    strategy: 'override',
    transition: {
      enterActiveClass: 'transition ease-out duration-200',
      enterFromClass: 'opacity-0',
      enterToClass: 'opacity-100',
      leaveActiveClass: 'transition ease-in duration-150',
      leaveFromClass: 'opacity-100',
      leaveToClass: 'opacity-0'
    }
  },
  transition: {
    enterActiveClass: 'overflow-hidden transition-[height] duration-200 ease-out',
    leaveActiveClass: 'overflow-hidden transition-[height] duration-200 ease-out'
  }
}