仪表盘侧边栏

GitHub
一个可调整大小和可折叠的侧边栏,用于在仪表盘中显示。

用法

DashboardSidebar 组件用于显示侧边栏。其状态(大小、折叠等)将根据您提供给 DashboardGroup 组件的 storagestorage-key 属性进行保存。

DashboardGroup 组件的默认插槽中使用它

layouts/dashboard.vue
<template>
  <UDashboardGroup>
    <UDashboardSidebar />

    <slot />
  </UDashboardGroup>
</template>
当使用 resizable 属性时,此组件没有单个根元素,因此如果您使用页面过渡或需要单个根进行布局,请将其包装在容器中(例如,<div class="flex flex-1">)。

使用 leftdefaultright 插槽来自定义侧边栏,并使用 bodycontent 插槽来自定义侧边栏菜单。

<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'

const items: NavigationMenuItem[][] = [[{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox',
  badge: '4'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}, {
  label: 'Settings',
  icon: 'i-lucide-settings',
  defaultOpen: true,
  children: [{
    label: 'General'
  }, {
    label: 'Members'
  }, {
    label: 'Notifications'
  }]
}], [{
  label: 'Feedback',
  icon: 'i-lucide-message-circle',
  to: 'https://github.com/nuxt-ui-templates/dashboard',
  target: '_blank'
}, {
  label: 'Help & Support',
  icon: 'i-lucide-info',
  to: 'https://github.com/nuxt/ui',
  target: '_blank'
}]]
</script>

<template>
  <UDashboardSidebar collapsible resizable :ui="{ footer: 'border-t border-default' }">
    <template #header="{ collapsed }">
      <Logo v-if="!collapsed" class="h-5 w-auto shrink-0" />
      <UIcon v-else name="i-simple-icons-nuxtdotjs" class="size-5 text-primary mx-auto" />
    </template>

    <template #default="{ collapsed }">
      <UButton
        :label="collapsed ? undefined : 'Search...'"
        icon="i-lucide-search"
        color="neutral"
        variant="outline"
        block
        :square="collapsed"
      >
        <template v-if="!collapsed" #trailing>
          <div class="flex items-center gap-0.5 ms-auto">
            <UKbd value="meta" variant="subtle" />
            <UKbd value="K" variant="subtle" />
          </div>
        </template>
      </UButton>

      <UNavigationMenu
        :collapsed="collapsed"
        :items="items[0]"
        orientation="vertical"
      />

      <UNavigationMenu
        :collapsed="collapsed"
        :items="items[1]"
        orientation="vertical"
        class="mt-auto"
      />
    </template>

    <template #footer="{ collapsed }">
      <UButton
        :avatar="{
          src: 'https://github.com/benjamincanac.png'
        }"
        :label="collapsed ? undefined : 'Benjamin'"
        color="neutral"
        variant="ghost"
        class="w-full"
        :block="collapsed"
      />
    </template>
  </UDashboardSidebar>
</template>
将侧边栏拖到屏幕左边缘附近可折叠。

可调整大小

使用 resizable 属性使侧边栏可调整大小。

<template>
  <UDashboardSidebar resizable>
    <Placeholder class="h-96" />
  </UDashboardSidebar>
</template>

Collapsible

使用 collapsible 属性使侧边栏在拖动到屏幕边缘附近时可折叠。

如果侧边栏不可折叠,则 DashboardSidebarCollapse 组件将无效。
<template>
  <UDashboardSidebar resizable collapsible>
    <Placeholder class="h-96" />
  </UDashboardSidebar>
</template>
您可以在插槽属性中访问 collapsed 状态,以在侧边栏折叠时自定义其内容。

尺寸

使用 min-sizemax-sizedefault-sizecollapsed-size 属性来自定义侧边栏的大小。

<template>
  <UDashboardSidebar
    resizable
    collapsible
    :min-size="22"
    :default-size="35"
    :max-size="40"
    :collapsed-size="0"
  >
    <Placeholder class="h-96" />
  </UDashboardSidebar>
</template>
默认情况下,大小按百分比计算。您可以使用 DashboardGroup 组件上的 unit 属性更改此设置。
默认情况下,collapsed-size 属性设置为 0,但侧边栏具有 min-w-16 以确保其可见。

方向

使用 side 属性更改侧边栏的侧面。默认为 left

<template>
  <UDashboardSidebar side="right" resizable collapsible>
    <Placeholder class="h-96" />
  </UDashboardSidebar>
</template>

模式

使用 mode 属性更改侧边栏菜单的模式。默认为 slideover

使用 body 插槽填充菜单主体(标题下方),或使用 content 插槽填充整个菜单。

您可以使用 menu 属性来自定义侧边栏菜单,它将根据您选择的模式进行调整。
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'

defineProps<{
  mode: 'drawer' | 'slideover' | 'modal'
}>()

const items: NavigationMenuItem[] = [{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}]
</script>

<template>
  <UDashboardGroup>
    <UDashboardSidebar :mode="mode">
      <template #header="{ collapsed }">
        <Logo v-if="!collapsed" class="h-5 w-auto" />
        <UIcon v-else name="i-simple-icons-nuxtdotjs" class="size-5 text-primary mx-auto" />
      </template>

      <UNavigationMenu
        :items="items"
        orientation="vertical"
      />
    </UDashboardSidebar>

    <UDashboardPanel>
      <template #header>
        <UDashboardNavbar title="Dashboard" />
      </template>
    </UDashboardPanel>
  </UDashboardGroup>
</template>
这些示例包含 DashboardGroupDashboardPanelDashboardNavbar 组件,因为它们是在移动设备上演示侧边栏所必需的。

Toggle

使用 toggle 属性自定义在移动设备上显示的 DashboardSidebarToggle 组件。

您可以传递 Button 组件的任何属性来自定义它。

<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'

const items: NavigationMenuItem[] = [{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}]
</script>

<template>
  <UDashboardGroup>
    <UDashboardSidebar
      open
      :toggle="{
        color: 'primary',
        variant: 'subtle',
        class: 'rounded-full'
      }"
    >
      <template #header>
        <Logo class="h-5 w-auto" />
      </template>

      <UNavigationMenu
        :items="items"
        orientation="vertical"
      />
    </UDashboardSidebar>

    <UDashboardPanel>
      <template #header>
        <UDashboardNavbar title="Dashboard" />
      </template>
    </UDashboardPanel>
  </UDashboardGroup>
</template>

切换侧边

使用 toggle-side 属性更改切换按钮的侧面。默认为 left

<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'

const items: NavigationMenuItem[] = [{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}]
</script>

<template>
  <UDashboardGroup>
    <UDashboardSidebar
      open
      toggle-side="right"
    >
      <template #header>
        <Logo class="h-5 w-auto" />
      </template>

      <UNavigationMenu
        :items="items"
        orientation="vertical"
      />
    </UDashboardSidebar>

    <UDashboardPanel>
      <template #header>
        <UDashboardNavbar title="Dashboard" />
      </template>
    </UDashboardPanel>
  </UDashboardGroup>
</template>

示例

控制打开状态

您可以使用 open 属性或 v-model:open 指令控制打开状态。

<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'

const items: NavigationMenuItem[] = [{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}]

const open = ref(true)

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

<template>
  <UDashboardSidebar v-model:open="open">
    <template #header="{ collapsed }">
      <Logo v-if="!collapsed" class="h-5 w-auto" />
      <UIcon v-else name="i-simple-icons-nuxtdotjs" class="size-5 text-primary mx-auto" />
    </template>

    <UNavigationMenu
      :items="items"
      orientation="vertical"
    />
  </UDashboardSidebar>
</template>
在此示例中,利用 defineShortcuts,您可以通过按 O 来切换 DashboardSidebar 的打开状态。

控制折叠状态

您可以使用 collapsed 属性或 v-model:collapsed 指令控制折叠状态。

<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'

const items: NavigationMenuItem[] = [{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}]

const collapsed = ref(false)

defineShortcuts({
  c: () => collapsed.value = !collapsed.value
})
</script>

<template>
  <UDashboardSidebar v-model:collapsed="collapsed" collapsible>
    <template #header>
      <Logo v-if="!collapsed" class="h-5 w-auto" />
      <UIcon v-else name="i-simple-icons-nuxtdotjs" class="size-5 text-primary mx-auto" />
    </template>

    <UNavigationMenu
      :collapsed="collapsed"
      :items="items"
      orientation="vertical"
    />
  </UDashboardSidebar>
</template>
在此示例中,利用 defineShortcuts,您可以通过按 C 来切换 DashboardSidebar 的折叠状态。

API

属性

属性默认值类型
mode

'slideover'

"modal" | "slideover" | "drawer"

侧边栏菜单的模式。

菜单

ModalProps | SlideoverProps | DrawerProps

侧边栏菜单组件的属性。

toggle

true

布尔值 | 部分<ButtonProps>

一个用于在移动设备上切换侧边栏的按钮。

toggleSide

'left'

渲染切换按钮的侧边位置。

id

useId()

string

面板的 ID。

side

'left'

"left" | "right"

渲染面板的侧面。

最小尺寸

10

number

面板的最小尺寸。

最大尺寸

20

number

面板的最大尺寸。

默认尺寸

15

number

面板的默认尺寸。

可调整大小

false

boolean

是否允许用户调整面板大小。

collapsible

false

boolean

是否允许用户折叠面板。

折叠尺寸

0

number

面板折叠时的大小。

open

false

boolean

collapsed

false

boolean

ui

{ root?: ClassNameValue; header?: ClassNameValue; body?: ClassNameValue; footer?: ClassNameValue; toggle?: ClassNameValue; handle?: ClassNameValue; content?: ClassNameValue; overlay?: ClassNameValue; }

插槽

插槽类型
页头
default
页脚

{ collapsed?: boolean | undefined; collapse?: ((value: boolean) => void) | undefined; }

toggle

{ open: boolean; toggle: () => void; ui: object; }

内容

{ close?: (() => void) | undefined; }

调整大小手柄

{ onMouseDown: (e: MouseEvent) => void; onTouchStart: (e: TouchEvent) => void; onDoubleClick: (e: MouseEvent) => void; ui: object; }

主题

app.config.ts
export default defineAppConfig({
  ui: {
    dashboardSidebar: {
      slots: {
        root: 'relative hidden lg:flex flex-col min-h-svh min-w-16 w-(--width) shrink-0',
        header: 'h-(--ui-header-height) shrink-0 flex items-center gap-1.5 px-4',
        body: 'flex flex-col gap-4 flex-1 overflow-y-auto px-4 py-2',
        footer: 'shrink-0 flex items-center gap-1.5 px-4 py-2',
        toggle: '',
        handle: '',
        content: 'lg:hidden',
        overlay: 'lg:hidden'
      },
      variants: {
        menu: {
          true: {
            header: 'sm:px-6',
            body: 'sm:px-6',
            footer: 'sm:px-6'
          }
        },
        side: {
          left: {
            root: 'border-e border-default'
          },
          right: {
            root: ''
          }
        },
        toggleSide: {
          left: {
            toggle: ''
          },
          right: {
            toggle: 'ms-auto'
          }
        }
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        dashboardSidebar: {
          slots: {
            root: 'relative hidden lg:flex flex-col min-h-svh min-w-16 w-(--width) shrink-0',
            header: 'h-(--ui-header-height) shrink-0 flex items-center gap-1.5 px-4',
            body: 'flex flex-col gap-4 flex-1 overflow-y-auto px-4 py-2',
            footer: 'shrink-0 flex items-center gap-1.5 px-4 py-2',
            toggle: '',
            handle: '',
            content: 'lg:hidden',
            overlay: 'lg:hidden'
          },
          variants: {
            menu: {
              true: {
                header: 'sm:px-6',
                body: 'sm:px-6',
                footer: 'sm:px-6'
              }
            },
            side: {
              left: {
                root: 'border-e border-default'
              },
              right: {
                root: ''
              }
            },
            toggleSide: {
              left: {
                toggle: ''
              },
              right: {
                toggle: 'ms-auto'
              }
            }
          }
        }
      }
    })
  ]
})

更新日志

63c0a— feat: 在使用的 slot prop 中暴露 ui (#5207)

5cb65— 特性:导入 @nuxt/ui-pro 组件