Любой сайт содержит какие-либо повторяющиеся элементы, например , заголовок (header) с логотипом, подвал (footer), панель навигации и так далее. Повторять это содержимое вручную от страницы к странице — лишняя трата времени и сил. Для таких случаев в Blazor предусмотрены макеты. Макеты в Blazor — это компоненты, содержащие какие-либо постоянно повторяющиеся элементы страницы для всего приложения или отдельное его области.
Структура страницы в Blazor Server
Применительно к теме макетов в Blazor, структуру приложения Blazor Server можно представить следующим образом:
В файле _Layout.cshtml
задаётся макет для корневой страницы приложения _Host.cshtml
, которая загружается при любом запросе первой. В шаблоне содержится наиболее общий html-код без которого наше приложение не сможет, в принципе, нормально работать:
@using Microsoft.AspNetCore.Components.Web @namespace BlazorApp1.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <base href="~/" /> <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" /> <link href="css/site.css" rel="stylesheet" /> <link href="BlazorApp1.styles.css" rel="stylesheet" /> <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" /> </head> <body> @RenderBody() <div id="blazor-error-ui"> <environment include="Staging,Production"> An error has occurred. This application may no longer respond until reloaded. </environment> <environment include="Development"> An unhandled exception has occurred. See browser dev tools for details. </environment> <a href="" class="reload">Reload</a> <a class="dismiss">🗙</a> </div> <script src="_framework/blazor.server.js"></script> </body> </html>
Здесь мы видим вызов метода @RenderBody()
, который, по сути, является неким плейсхолдером для того, чтобы на его место вставлялось содержимое других страниц.
Следующий файл, отвечающий уже за внешний вид нашего приложения — MainLayout.razor
. Название говорит само за себя — это главный макет приложения. Как раз его содержимое встает на место @RenderBody()
. Содержимое файла:
@inherits LayoutComponentBase <PageTitle>BlazorApp2</PageTitle> <div class="page"> <div class="sidebar"> <NavMenu /> </div> <main> <div class="top-row px-4"> <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a> </div> <article class="content px-4"> @Body </article> </main> </div>
Здесь мы уже видим, что компонент MainLayout.razor
наследуется от LayoutComponentBase
.
Именно LayoutComponentBase
предоставляет нам в дальнейшем работать с таким типом данных как RenderFragment
, который мы рассматривали здесь.
Также, LayoutComponentBase
предоставляет свойство @Body
, которое аналогично @RenderBody()
— указывает в каком месте макета вставлять содержимое компонента Blazor.
В главном макете приложения описывается именно то, как визуально будет выглядеть наше приложения — сайдбар с меню, расположение контента, header, footer и т.д.
Соответственно, на место @Body
в работающем приложении подставляется содержимое всех наших компонентов Blazor. Так как компонент MainLayout.razor
является общим для всего приложения, то содержится он в папке Shared
приложения.
Также стоит отметить, что Blazor поддерживает раздельное указание стилей CSS для компонентов. Чтобы определить для какого-либо компонента Blazor свой собственный файл css, необходимо создать файл с именем [имя_компонента].razor.css
. Так, например, компоненты MainLayout
и NavMenu
имеют свои собственные css-файлы со стилями.
Создание шаблона для отдельной области
Практически на любом сайте могут выделяться отдельные области (части), предназначенные для определенного круга лиц. Например, на этом сайте можно выделить, как минимум, две области:
- блог — виден всем желающим
- панель администратора — видна только администратору сайта или его авторам (если авторов несколько)
Соответственно и выглядеть каждая область сайта может по своему. Для того, чтобы задать отдельной области свой собственный макет, в Blazor необходимо выполнить ряд обязательных действий. Например, создадим в шаблонном проекте Blazor Server отдельную область для администратора.
1. Создаем отдельную папку, например, «AdminPanel»
2. Создаем в папке Shared компонент Blazor, который будет являться шаблоном для всех страниц из панели администратора, например, «AdminLayout.razor»
В этом файле мы должны создать html-разметку нашего макета, а также указать в каком месте необходимо выводить содержимое страниц. Для примера, пусть макет содержит следующий код:
@inherits LayoutComponentBase <h1>Это шаблон панели администратора</h1> <p>Ниже будут показаны все компоненты, относящиеся к области AdminPanel</p> @Body <p>Это условный футер в панели администратора</p>
3. В папке AdminPanel создаем файл _Imports.razor
:
В этом файле указываем макет для области:
@layout AdminLayout
На этом подключение отдельного шаблона для области AdminPanel закончено. Для примера также создадим в папке AdminPanel какой-нибудь компонент Blazor, например, Users.razor
для вывода списка пользователей:
@page "/admin/users" <h3>Список пользоватлей</h3> <p>Какой-то список</p> @code { }
Теперь запустим приложение и убедимся, что для основной части приложения сохранился шаблон по умолчанию:
а при переходе на страницу https://localhost:7036/admin/users открывается страница с нашим новым шаблоном:
Итого
Для того, чтобы создать свой макет для отдельной области в приложении Blazor мы добавили следующие файлы и папки:
Папка
AdminPanel
— отдельная область приложения для которой необходимо установить свой шаблон- Файл
AdminLayout.razor
— компонент шаблона для области AdmiPanel. Размещать этот файл можно в любом месте проекта, главное, чтобы приложение имело к нему доступ (папка Shared доступна всегда) - Файл
_Imports.razor
— файл в котором указывается имя компонента-шаблона Blazor для области. Этот файл располагается строго в папке отдельной области и должен называться именно так, как есть.