Vaadin 23中如何实现层级导航菜单
Vaadin 23 层级导航菜单实现方案
Vaadin 10+ 版本重构全量流组件后,确实移除了V8版本中经典的Tree组件,现有TreeGrid为表格型层级数据场景设计,自带列头、表格行选择、大数据表格虚拟滚动等特性,官方明确不适合作为导航菜单使用,不需要硬套现有组件,可以通过以下几种方式实现符合要求的左侧层级导航:
原生组件组合实现(最推荐,无额外依赖)
这也是Vaadin官方示例中采用的实现方式,完全基于框架自带组件搭建,无额外依赖,样式和交互灵活度最高:- 整体框架用
AppLayout搭建,将左侧区域固定为导航栏容器 - 带下级菜单的父级节点用带图标、展开箭头的
Button实现,点击时切换子菜单容器的显隐状态,同步旋转箭头图标给出交互反馈 - 可直接跳转的叶子节点用
RouterLink实现,自动绑定路由、支持当前激活路由的高亮样式 - 层级缩进通过给子菜单容器增加左侧内边距实现,不需要额外复杂逻辑
简单两级菜单的实现参考代码:
// 侧边导航根容器 VerticalLayout sideNav = new VerticalLayout(); sideNav.setWidth("240px"); sideNav.setPadding(false); sideNav.setSpacing(false); sideNav.addClassName("side-nav-container"); // 一级父菜单项:系统管理 Div sysManageSubMenu = new Div(); sysManageSubMenu.setVisible(false); // 默认折叠 Button sysManageBtn = new Button("系统管理", VaadinIcon.COGS.create(), click -> { boolean isExpanded = sysManageSubMenu.isVisible(); sysManageSubMenu.setVisible(!isExpanded); click.getSource().getIcon().getStyle().set("transform", !isExpanded ? "rotate(90deg)" : "rotate(0deg)"); }); sysManageBtn.setWidthFull(); sysManageBtn.addClassName("nav-parent-item"); // 二级子菜单项 RouterLink userPage = new RouterLink("用户管理", UserManageView.class); userPage.addClassName("nav-leaf-item"); RouterLink rolePage = new RouterLink("角色管理", RoleManageView.class); rolePage.addClassName("nav-leaf-item"); sysManageSubMenu.add(userPage, rolePage); sysManageSubMenu.addClassNames("pl-m", "flex", "flex-col", "gap-xs"); sideNav.add(sysManageBtn, sysManageSubMenu);如果需要支持无限层级菜单,只需要将单级菜单封装为可递归渲染的自定义组件,根据菜单数据结构递归生成节点即可,逻辑和两级菜单完全一致。
- 整体框架用
引入社区成熟树形菜单组件
如果不想自行实现展开折叠、递归渲染、键盘导航等通用逻辑,可以直接使用社区维护的、专门为导航场景设计的树形菜单组件,这类组件API和V8版本的Tree组件高度相似,开箱支持层级数据绑定、展开折叠状态记忆、路由高亮、无障碍访问等特性,没有TreeGrid的冗余表格功能,引入对应依赖即可直接使用。不推荐方案
不要强行修改TreeGrid样式、隐藏表格特性来模拟导航菜单,这种实现方式版本兼容性差,TreeGrid自带的表格虚拟滚动、单元格渲染等逻辑在导航场景下还会带来不必要的性能开销,和官方的组件使用建议相悖。
内容的提问来源于stack exchange,提问作者Kivan
相关产品推荐
相关产品推荐

