- 手风琴 (Accordion)
- 警告 (Alert)
- 警告对话框 (Alert Dialog)
- 宽高比 (Aspect Ratio)
- 头像 (Avatar)
- 徽章 (Badge)
- 面包屑 (Breadcrumb)
- 按钮 (Button)
- 按钮组 (Button Group)
- 日历 (Calendar)
- 卡片 (Card)
- 轮播图 (Carousel)
- 图表 (Chart)
- 复选框 (Checkbox)
- 折叠面板 (Collapsible)
- 组合框 (Combobox)
- 命令面板 (Command)
- 上下文菜单 (Context Menu)
- 数据表格 (Data Table)
- 日期选择器 (Date Picker)
- 对话框 (Dialog)
- 抽屉 (Drawer)
- 下拉菜单 (Dropdown Menu)
- 空状态 (Empty)
- 字段 (Field)
- 表单 (Form)
- 悬停卡片 (Hover Card)
- 输入框 (Input)
- 输入组 (Input Group)
- 验证码输入 (Input OTP)
- 项 (Item)
- 键盘按键 (Kbd)
- 标签 (Label)
- 菜单栏 (Menubar)
- 原生选择器 (Native Select)
- 导航菜单 (Navigation Menu)
- 数字输入框 (Number Field)
- 分页 (Pagination)
- 引脚输入 (Pin Input)
- 气泡卡片 (Popover)
- 进度条 (Progress)
- 单选框组 (Radio Group)
- 范围日历 (Range Calendar)
- 可调整大小 (Resizable)
- 滚动区域 (Scroll Area)
- 选择器 (Select)
- 分隔线 (Separator)
- 侧边栏抽屉 (Sheet)
- 侧边栏 (Sidebar)
- 骨架屏 (Skeleton)
- 滑块 (Slider)
- 轻量提示 (Sonner)
- 加载动画 (Spinner)
- 步骤条 (Stepper)
- 开关 (Switch)
- 表格 (Table)
- 标签页 (Tabs)
- 标签输入 (Tags Input)
- 文本域 (Textarea)
- 吐司提示 (Toast)
- 切换按钮 (Toggle)
- 切换按钮组 (Toggle Group)
- 工具提示 (Tooltip)
- 排版 (Typography)


侧边栏是构建难度最高的组件之一。它们是任何应用程序的核心,且通常包含许多动态部分。
我不喜欢构建侧边栏。所以我构建了 30 多个。各种各样的配置。然后我将核心组件提取为 Sidebar*.vue。
现在我们有了一个坚实的基础。可组合。可主题化。可自定义。
安装
pnpm dlx shadcn-vue@latest add sidebar
结构
Sidebar 组件由以下部分组成
SidebarProvider- 处理折叠状态。Sidebar- 侧边栏容器。SidebarHeader和 SidebarFooter - 侧边栏顶部和底部的固定区域SidebarContent- 可滚动内容区域。SidebarGroup- SidebarContent 内的区块。SidebarTrigger- 侧边栏触发器


使用方法
<script setup lang="ts">
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarHeader,
SidebarInset,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarProvider,
SidebarRail,
SidebarTrigger,
} from '@/components/ui/sidebar'
</script>
<template>
<SidebarProvider>
<Sidebar>
<SidebarHeader>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton size="lg">
<div class="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
<GalleryVerticalEnd class="size-4" />
</div>
<div class="grid flex-1 text-left text-sm leading-tight">
<span class="truncate font-semibold">Acme Inc</span>
<span class="truncate text-xs">Enterprise</span>
</div>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Platform</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton as-child>
<a href="#">
<Home />
<span>Home</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
<SidebarFooter />
<SidebarRail />
</Sidebar>
<SidebarInset>
<header class="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12">
<div class="flex items-center gap-2 px-4">
<SidebarTrigger class="-ml-1" />
</div>
</header>
<div class="flex flex-1 flex-col gap-4 p-4 pt-0">
<div class="grid auto-rows-min gap-4 md:grid-cols-3">
<div class="aspect-video rounded-xl bg-muted/50" />
<div class="aspect-video rounded-xl bg-muted/50" />
<div class="aspect-video rounded-xl bg-muted/50" />
</div>
<div class="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
</div>
</SidebarInset>
</SidebarProvider>
</template>你的第一个侧边栏
让我们从最基本的侧边栏开始,一个带有菜单的可折叠侧边栏。
在应用程序的根目录添加 SidebarProvider 和 SidebarTrigger
<script setup lang="ts">
import AppSidebar from '@/components/AppSidebar.vue'
import { SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar'
</script>
<template>
<SidebarProvider>
<AppSidebar />
<main>
<SidebarTrigger />
<slot />
</main>
</SidebarProvider>
</template>在 @/components/AppSidebar.vue 创建一个新的侧边栏组件
<script setup lang="ts">
import { Sidebar, SidebarContent } from '@/components/ui/sidebar'
</script>
<template>
<Sidebar>
<SidebarContent />
</Sidebar>
</template>现在,让我们在侧边栏中添加一个 SidebarMenu
我们将会在 SidebarGroup 中使用 SidebarMenu 组件。
<script setup lang="ts">
import { Calendar, Home, Inbox, Search, Settings } from 'lucide-vue-next'
import {
Sidebar,
SidebarContent,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from '@/components/ui/sidebar'
// Menu items.
const items = [
{
title: 'Home',
url: '#',
icon: Home,
},
{
title: 'Inbox',
url: '#',
icon: Inbox,
},
{
title: 'Calendar',
url: '#',
icon: Calendar,
},
{
title: 'Search',
url: '#',
icon: Search,
},
{
title: 'Settings',
url: '#',
icon: Settings,
},
]
</script>
<template>
<Sidebar>
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Application</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
<SidebarMenuItem v-for="item in items" :key="item.title">
<SidebarMenuButton as-child>
<a :href="item.url">
<component :is="item.icon" />
<span>{{ item.title }}</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>
</template>你已经创建了你的第一个侧边栏。
你应该能看到类似这样的内容


组件
Sidebar*.vue 文件中的组件被设计为可组合的,即通过组合提供的组件来构建你的侧边栏。它们也能与其他的 shadcn-vue 组件很好地配合使用,例如 DropdownMenu、Collapsible、Dialog 等。
如果你需要修改 Sidebar*.vue 文件中的代码,鼓励这样做。这些代码属于你。将提供的组件作为起点来构建你自己的组件。
SidebarProvider
SidebarProvider 组件用于为所有子组件提供侧边栏上下文。
Props
SidebarProvider 组件接受以下 props
宽度
使用 defaultOpen、open 和 onOpenChange props 来控制侧边栏的打开状态。
<script setup lang="ts">
import { ref } from 'vue'
const open = ref(false)
</script>
<template>
<SidebarProvider :open="open" @update:open="open = $event">
<!-- ... -->
</SidebarProvider>
</template>键盘快捷键
SidebarProvider 组件支持通过键盘快捷键切换侧边栏。默认快捷键是 cmd+b 或 ctrl+b。
<SidebarProvider>
<!-- ... -->
</SidebarProvider>持久化状态
要持久化侧边栏状态,你可以在 SidebarProvider 组件上使用 storageKey prop。
<SidebarProvider storage-key="sidebar">
<!-- ... -->
</SidebarProvider><SidebarProvider
:default-open="false"
storage-key="sidebar"
class="flex min-h-screen"
>
<!-- ... -->
</SidebarProvider>侧边栏
主要的侧边栏组件。
<Sidebar>
<SidebarHeader />
<SidebarContent />
<SidebarFooter />
</Sidebar>Props
Sidebar 组件接受以下 props
side
使用 side prop 设置侧边栏所在的一侧。
<Sidebar side="left">
<!-- ... -->
</Sidebar>variant
使用 variant prop 设置侧边栏的变体。
<!-- Default variant -->
<Sidebar variant="sidebar">
<!-- ... -->
</Sidebar><!-- Floating variant -->
<Sidebar variant="floating">
<!-- ... -->
</Sidebar><!-- Inset variant -->
<Sidebar variant="inset">
<!-- ... -->
</Sidebar>collapsible
使用 collapsible prop 使侧边栏可折叠。
<Sidebar collapsible="icon">
<!-- ... -->
</Sidebar><Sidebar collapsible="offcanvas">
<!-- ... -->
</Sidebar>useSidebar
useSidebar 钩子用于控制侧边栏。
<script setup lang="ts">
import { useSidebar } from '@/components/ui/sidebar'
const {
state,
open,
setOpen,
openMobile,
setOpenMobile,
isMobile,
toggleSidebar,
} = useSidebar()
</script>SidebarHeader
用于渲染侧边栏头部。
<Sidebar>
<SidebarHeader>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton size="lg">
<div class="flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
<GalleryVerticalEnd class="size-4" />
</div>
<div class="flex flex-col gap-0.5 leading-none">
<span class="font-semibold">Documentation</span>
<span class="">v1.0.0</span>
</div>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarHeader>
</Sidebar>SidebarFooter
用于渲染侧边栏底部。
<Sidebar>
<SidebarFooter>
<SidebarMenu>
<SidebarMenuItem>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<SidebarMenuButton>
<User2 /> Username
<ChevronUp class="ml-auto" />
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent
side="top"
class="w-(--reka-popper-anchor-width)"
>
<DropdownMenuItem>
<span>Account</span>
</DropdownMenuItem>
<DropdownMenuItem>
<span>Billing</span>
</DropdownMenuItem>
<DropdownMenuItem>
<span>Sign out</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
</Sidebar>SidebarContent
侧边栏的可滚动内容区域。
<Sidebar>
<SidebarContent>
<SidebarGroup />
<SidebarGroup />
</SidebarContent>
</Sidebar>SidebarGroup
用于对侧边栏菜单项进行分组。
<SidebarContent>
<SidebarGroup>
<SidebarGroupLabel>Application</SidebarGroupLabel>
<SidebarGroupContent>
<!-- SidebarMenu -->
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>可折叠的 SidebarGroup
要使 SidebarGroup 可折叠,请将其包裹在 Collapsible 组件中。
<SidebarGroup as-child>
<Collapsible default-open class="group/collapsible">
<SidebarGroupLabel as-child>
<CollapsibleTrigger class="group/label w-full text-left text-sm text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground [&[data-state=open]>svg]:rotate-90">
Help
<ChevronRight class="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90" />
</CollapsibleTrigger>
</SidebarGroupLabel>
<CollapsibleContent>
<SidebarGroupContent>
<SidebarMenu>
<!-- Menu items -->
</SidebarMenu>
</SidebarGroupContent>
</CollapsibleContent>
</Collapsible>
</SidebarGroup>SidebarGroupAction
SidebarGroupAction 组件用于在侧边栏组头部渲染操作按钮。
<SidebarGroup>
<SidebarGroupLabel>
Projects
<SidebarGroupAction>
<Plus /> <span class="sr-only">Add Project</span>
</SidebarGroupAction>
</SidebarGroupLabel>
<SidebarGroupContent></SidebarGroupContent>
</SidebarGroup>SidebarMenu
SidebarMenu 组件用于在侧边栏中渲染菜单。
<SidebarGroupContent>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton as-child>
<a href="#">
<Home />
<span>Home</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton as-child>
<a href="#">
<Inbox />
<span>Inbox</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroupContent>SidebarMenuButton
SidebarMenuButton 组件用于在侧边栏中渲染菜单按钮。
链接或锚点
使用 as-child prop 将 SidebarMenuButton 渲染为链接或锚点。
<SidebarMenuButton as-child>
<a href="#">
<Home />
<span>Home</span>
</a>
</SidebarMenuButton>图标和标签
你可以在 SidebarMenuButton 组件中渲染图标和标签。
<SidebarMenuButton>
<Home />
<span>Home</span>
</SidebarMenuButton>isActive
使用 isActive prop 将菜单按钮标记为激活状态。
<SidebarMenuButton :is-active="true">
<Home />
<span>Home</span>
</SidebarMenuButton>SidebarMenuAction
SidebarMenuAction 组件用于在侧边栏中渲染菜单操作。
<SidebarMenuItem>
<SidebarMenuButton>
<Home />
<span>Home</span>
</SidebarMenuButton>
<SidebarMenuAction>
<MoreHorizontal />
</SidebarMenuAction>
</SidebarMenuItem>DropdownMenu
你可以将 SidebarMenuAction 组件与 DropdownMenu 组件一起使用。
<SidebarMenuItem>
<SidebarMenuButton>
<Home />
<span>Home</span>
</SidebarMenuButton>
<DropdownMenu>
<DropdownMenuTrigger as-child>
<SidebarMenuAction>
<MoreHorizontal />
</SidebarMenuAction>
</DropdownMenuTrigger>
<DropdownMenuContent side="right" align="start">
<DropdownMenuItem>
<span>Edit Project</span>
</DropdownMenuItem>
<DropdownMenuItem>
<span>Delete Project</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>SidebarMenuSub
SidebarMenuSub 组件用于在侧边栏中渲染子菜单。
<SidebarMenuItem>
<SidebarMenuButton>
<Home />
<span>Home</span>
</SidebarMenuButton>
<SidebarMenuSub>
<SidebarMenuItem>
<SidebarMenuButton>
<span>History</span>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<span>Starred</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenuSub>
</SidebarMenuItem>可折叠的 SidebarMenu
要使 SidebarMenu 可折叠,请将其包裹在 Collapsible 组件中。
<SidebarMenuItem>
<Collapsible default-open class="group/collapsible">
<CollapsibleTrigger as-child>
<SidebarMenuButton>
<Home />
<span>Home</span>
<ChevronRight class="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90" />
</SidebarMenuButton>
</CollapsibleTrigger>
<CollapsibleContent>
<SidebarMenuSub>
<SidebarMenuItem>
<SidebarMenuButton>
<span>History</span>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<span>Starred</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenuSub>
</CollapsibleContent>
</Collapsible>
</SidebarMenuItem>SidebarMenuBadge
SidebarMenuBadge 组件用于在侧边栏菜单中渲染徽章。
<SidebarMenuButton>
<Home />
<span>Home</span>
<SidebarMenuBadge>24</SidebarMenuBadge>
</SidebarMenuButton>SidebarMenuSkeleton
你可以使用 SidebarMenuSkeleton 组件在侧边栏菜单中渲染骨架加载器。
<SidebarMenu>
<SidebarMenuItem v-for="item in Array.from({ length: 5 })" :key="item">
<SidebarMenuSkeleton />
</SidebarMenuItem>
</SidebarMenu>SidebarSeparator
SidebarSeparator 组件用于在侧边栏中渲染分割线。
<SidebarContent>
<SidebarGroup />
<SidebarSeparator />
<SidebarGroup />
</SidebarContent>SidebarTrigger
SidebarTrigger 组件用于渲染侧边栏的触发按钮。
<SidebarTrigger />自定义触发器
你可以使用 useSidebar 钩子创建自定义触发器。
<script setup lang="ts">
import { useSidebar } from '@/components/ui/sidebar'
const { toggleSidebar } = useSidebar()
</script>
<template>
<Button @click="toggleSidebar">
Toggle Sidebar
</Button>
</template>SidebarRail
SidebarRail 组件用于在侧边栏中渲染侧轨。这通常用于在侧边栏折叠时通过悬停来切换侧边栏。
<Sidebar collapsible="icon">
<SidebarHeader />
<SidebarContent />
<SidebarFooter />
<SidebarRail />
</Sidebar>受控侧边栏
使用 open 和 onOpenChange props 来控制侧边栏。
<script setup lang="ts">
import { ref } from 'vue'
const open = ref(false)
</script>
<template>
<SidebarProvider :open="open" @update:open="open = $event">
<Sidebar />
</SidebarProvider>
</template>主题化
你可以使用 CSS 变量为侧边栏设置主题。
@layer base {
:root {
--sidebar-background: 0 0% 98%;
--sidebar-foreground: 240 5.3% 26.1%;
--sidebar-primary: 240 5.9% 10%;
--sidebar-primary-foreground: 0 0% 98%;
--sidebar-accent: 240 4.8% 95.9%;
--sidebar-accent-foreground: 240 5.9% 10%;
--sidebar-border: 220 13% 91%;
--sidebar-ring: 217.2 91.2% 59.8%;
}
.dark {
--sidebar-background: 240 5.9% 10%;
--sidebar-foreground: 240 4.8% 95.9%;
--sidebar-primary: 224.3 76.3% 48%;
--sidebar-primary-foreground: 0 0% 100%;
--sidebar-accent: 240 3.7% 15.9%;
--sidebar-accent-foreground: 240 4.8% 95.9%;
--sidebar-border: 240 3.7% 15.9%;
--sidebar-ring: 217.2 91.2% 59.8%;
}
}样式
以下是一些设置侧边栏样式的提示
- 使用
data-sidebar和data-state属性来设置侧边栏样式。 - 侧边栏会自动设置
--sidebar-widthCSS 变量。你可以利用它来调整主内容的布局。
本页内容
安装结构用法你的第一个侧边栏组件SidebarProviderProps宽度键盘快捷键持久化状态SidebarPropssidevariantcollapsibleuseSidebarSidebarHeaderSidebarFooterSidebarContentSidebarGroup可折叠的 SidebarGroupSidebarGroupActionSidebarMenuSidebarMenuButton链接或锚点图标和标签isActiveSidebarMenuActionDropdownMenuSidebarMenuSub可折叠的 SidebarMenuSidebarMenuBadgeSidebarMenuSkeletonSidebarSeparatorSidebarTrigger自定义触发器SidebarRail受控侧边栏主题化样式