基于 SvelteKit + BeerCSS 的多级菜单实现指南
本文将结合 SvelteKit 的路由特性与 BeerCSS 的 Material Design 风格,实现动态响应式多级菜单。包含菜单状态管理、样式定制、交互优化等核心功能,代码可直接用于企业级项目。
一、环境搭建与依赖配置
1. 创建 SvelteKit 项目
npm create svelte@latest multi-level-menu
cd multi-level-menu
npm install
2. 集成 Beer CSS
在 app.html
中引入 BeerCSS 的 CDN:
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/beercss@3.4.1/dist/beercss.min.css">
</head>
二、核心功能实现
2.1 菜单数据结构设计
// src/lib/types/menu.ts
export interface MenuItem {
id: string;
title: string;
icon?: string;
path?: string;
children?: MenuItem[];
isOpen?: boolean; // 控制子菜单展开状态
}
2.2 菜单状态管理
<!-- src/routes/+layout.svelte -->
<script lang="ts">
import { menuStore } from '$lib/stores/menu';
const menuData: MenuItem[] = [
{
id: 'dashboard',
title: '控制台',
icon: 'home',
path: '/dashboard'
},
{
id: 'products',
title: '产品管理',
icon: 'inventory_2',
children: [
{ id: 'list', title: '产品列表', path: '/products' },
{ id: 'add', title: '新增产品', path: '/products/new' }
]
}
];
menuStore.set(menuData);
</script>
三、菜单组件实现
3.1 主菜单组件
<!-- src/lib/components/MainMenu.svelte -->
<script lang="ts">
import { menuStore } from '$lib/stores/menu';
import SubMenu from './SubMenu.svelte';
$: menus = $menuStore;
</script>
<nav class="surface-container padding round">
{#each menus as menu}
<div class="menu-item {menu.isOpen ? 'active' : ''}">
<a
href={menu.path}
class="row gap-medium"
on:click|preventDefault={() => handleClick(menu)}
>
<i class="material-icons">{menu.icon}</i>
<span>{menu.title}</span>
{#if menu.children}
<i class="material-icons">{menu.isOpen ? 'expand_less' : 'expand_more'}</i>
{/if}
</a>
{#if menu.children && menu.isOpen}
<SubMenu items={menu.children} />
{/if}
</div>
{/each}
</nav>
<style>
.menu-item {
transition: background-color 0.3s;
border-radius: var(--shape-medium);
}
.menu-item.active {
background-color: var(--primary-container);
}
</style>
3.2 子菜单组件
<!-- src/lib/components/SubMenu.svelte -->
<script lang="ts">
export let items: MenuItem[];
</script>
<div class="submenu padding-left-large">
{#each items as item}
<a
href={item.path}
class="row gap-small padding-small round"
activeClass="active-submenu"
>
<i class="material-icons">chevron_right</i>
{item.title}
</a>
{/each}
</div>
<style>
.submenu {
border-left: 2px solid var(--outline);
}
.active-submenu {
color: var(--primary);
font-weight: 500;
}
</style>
四、交互优化技巧
4.1 动态路由高亮
<script>
import { page } from '$app/stores';
$: currentPath = $page.url.pathname;
</script>
<a
class:active={currentPath === item.path}
class="menu-link"
>
{item.title}
</a>
4.2 响应式折叠
<script>
import { browser } from '$app/environment';
function handleClick(menu: MenuItem) {
if (menu.children) {
menuStore.toggle(menu.id);
} else if (menu.path) {
goto(menu.path);
}
}
</script>
五、BeerCSS 样式增强
5.1 自定义主题变量
/* src/app.postcss */
:root {
--primary: #2196F3;
--surface-container: #f5f5f5;
--shape-medium: 8px;
}
.dark-mode {
--surface-container: #1e1e1e;
}
5.2 交互动画实现
.menu-item {
transition:
transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
box-shadow 0.3s ease;
}
.menu-item:hover {
transform: translateY(-2px);
box-shadow: var(--elevation-1);
}
参考文献
技术亮点总结:
- 采用响应式状态管理实现菜单动态展开
- 结合 BeerCSS 的 Material Design 规范与自定义主题
- 支持无限级嵌套菜单结构
- 实现路由自动高亮与平滑过渡动画
- 适配移动端触控操作
---
**扩展阅读建议**:
1. 通过 `svelte:head` 优化 SEO [30](@ref)
2. 结合 `svelte-i18n` 实现多语言菜单 [30](@ref)
3. 添加键盘导航支持提升可访问性 [40](@ref)
转载请注明出处并附上原文链接。