Каркас приложения: AppLayout
У большинства приложений есть каркас: шапка с названием сверху, меню слева и область, где меняются экраны. В Vaadin каркас делают один раз в классе-макете на основе AppLayout. Экраны вставляются в его центральную часть автоматически, и при переходе между ними шапка и меню не перерисовываются.
Макет приложения
// src/main/java/com/example/blog/views/MainLayout.java
package com.example.blog.views;
import com.vaadin.flow.component.applayout.AppLayout;
import com.vaadin.flow.component.applayout.DrawerToggle;
import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.sidenav.SideNav;
import com.vaadin.flow.component.sidenav.SideNavItem;
import com.vaadin.flow.router.Layout;
@Layout
public class MainLayout extends AppLayout {
public MainLayout() {
H1 title = new H1("Админка блога");
title.getStyle().set("font-size", "1.25rem").set("margin", "0");
SideNav nav = new SideNav();
nav.addItem(new SideNavItem("Привет", HelloView.class, VaadinIcon.HOME.create()));
nav.addItem(new SideNavItem("Черновик", DraftView.class, VaadinIcon.EDIT.create()));
addToNavbar(new DrawerToggle(), title);
addToDrawer(nav);
}
}Откройте http://localhost:8080/hello: сверху шапка с кнопкой-«гамбургером» и названием, слева меню из двух пунктов. Нажмите «Черновик» — меняется только центральная часть, а пункт меню подсвечивается как активный.
Части AppLayout
| Метод или класс | Что делает |
|---|---|
addToNavbar(...) | Кладёт компоненты в шапку |
addToDrawer(...) | Кладёт компоненты в выдвижную боковую панель |
DrawerToggle | Кнопка, которая прячет и показывает панель |
SideNav, SideNavItem | Меню навигации; пункт знает свой экран и подсвечивает себя |
setPrimarySection(Section.DRAWER) | Панель на всю высоту, шапка — справа от неё |
На узком экране телефона панель сама сворачивается, и открыть её можно кнопкой DrawerToggle.
Как экран попадает в макет
Аннотация @Layout делает класс макетом по умолчанию: все экраны с @Route автоматически показываются внутри него. Если экран не должен быть в каркасе (например, страница входа), отключите это:
// src/main/java/com/example/blog/views/HelloView.java (фрагмент)
@Route(value = "hello", autoLayout = false)
public class HelloView extends VerticalLayout {Теперь /hello открывается без шапки и меню.
Второй способ — указать макет явно у каждого экрана: @Route(value = "draft", layout = MainLayout.class). Он встречается в старых проектах; с @Layout писать это не нужно.
Пункты меню с подменю
SideNavItem может содержать вложенные пункты — получится раскрывающаяся группа:
// src/main/java/com/example/blog/views/MainLayout.java (фрагмент конструктора)
SideNavItem content = new SideNavItem("Контент");
content.addItem(new SideNavItem("Черновик", DraftView.class));
nav.addItem(content);В меню появляется пункт «Контент» со стрелкой, внутри — «Черновик».
Частая ошибка
Макет написан, но экраны показываются без него. Проверьте две вещи: на классе макета стоит @Layout, и у экрана нет autoLayout = false. Ещё одна причина — макет не наследует AppLayout или другой класс с интерфейсом RouterLayout: тогда Vaadin не знает, куда вставлять экран, и при запуске сообщает об этом ошибкой.