Компоновка или layout позволяет задать для приложения некоторый единый шаблон и применяется для создания единообразного, унифицированного графического интерфейса. Благодаря компоновки мы можем определить единые элементы для всех компонентов, и нам не потребуется определять эти элементы для каждого отдельного компонента. В приложении Blazor компоновка обеспечивается компонентов компоновки.
Компонент компоновки представляет стандартный компонент Blazor, который обладает всеми возможностями, что и другие компоненты Blazor, но при этом также имеет две особенности:
Компонент компоновки наследуется от класса LayoutComponentBase. Данный класс определяет
свойство Body, который содержит вложенное содержимое в виде объекта RenderFragment
Компонент компоновки использует выражение @Body
для рендеринга вложенного содержимого в определенной части компонента
Пусть у нас есть проект со следующими компонентами:
В папке Components определено три однотипных компонента, которые будут сопоставляться с маршрутами. Компонент Home
@page "/" <h2>Home Page</h2>
Компонент Contacts:
@page "/contacts" <h2>Contacts Page</h2>
Компонент About:
@page "/about" <h2>About Page</h2>
В папке Companents/Layouts определим компонент MainLayout со следующим кодом:
@inherits LayoutComponentBase <div> <div> <a href="/">Home</a> | <a href="contacts">Contacts</a> | <a href="about">About</a> </div> <div> @Body </div> </div>
Это и есть компонент компоновки, который определяет общий каркас графического интерфейса. Компоненты компоновки необязательно должны помещаться в отдельный каталог, в данном случае я так сделал,
чтобы отделить данный компонент от основных компонентов. Благодаря применению директивы @inherits
он наследуется от класса LayoutComponentBase
. Для навигации между компонентами он определяет меню. Кроме того, использует выражение @Body
,
вместо которого будет вставляться содержимое определенного компонента - Home, Contacts или About.
Для использования компонента компоновки в процессе маршрутизации у компонента RouteView
определено свойство DefaultLayout, которое принимает
тип компонента компоновки. Так, определим в компоненте App следующий код:
@using Microsoft.AspNetCore.Components.Routing @** пространство имен компонента MainLayout **@ @using BlazorApp.Components.Layouts <!DOCTYPE html> <html> <head> <title>METANIT.COM</title> <meta charset="utf-8" /> <base href="/" /> </head> <body> <Router AppAssembly="@typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" DefaultLayout="@typeof(MainLayout)" /> </Found> </Router> <script src="_framework/blazor.web.js"></script> </body> </html>
Здесь с помощью атрибута DefaultLayout="@typeof(MainLayout)"
у компонента RouteView в качестве компонента компоновки устанавливается класс MainLayout.
И если мы запустим проект, то структура приложения будет определяться компонентом компоновки MainLayout, а при переходе по ссылкам он будет вставлять вместо @Body
содержимое выбранного компонента:
С помощью директивы @layout на уровне отдельно компонента можно переустановить компонент компоновки. Такой компонент должен быть маршрутизируемым, то есть применять директиву
@page
для обработки запросов по определенным маршрутам. Например, пусть в папке Components/Layout у нас будет файл SecondLayout.razor:
Пусть этот компонент будет содержать следующий код:
@inherits LayoutComponentBase <div> <h1>Специальный раздел</h1> <div> @Body </div> </div>
Опять же данный компонент наследуюется от класса LayoutComponentBase, благодаря чему представляет компонент компоновки. Чтобы он отличался от MainLayout для демонстрации я убрал менб и заменил его заголовком. Но также здесь применяется директива @Body, через которую будет вставляться код компонента, применяемого для обработки запроса.
К примеру, применим данную компоновку в компоненте Contact.razor:
@page "/contacts" @layout BlazorApp.Components.Layouts.SecondLayout <h2>Контакты</h2>
Здесь второй строкой применяем компоновку из SecondLayout. В итоге при обращении к данному компоненту мы увидим применение компоновки SecondLayout:
Если наше приложение довольно большое, в нем много компонентов, то может возникнуть задача применять к разным группам компонентов рязную компоновку. Прописывать для каждого компонента
директиву @layout
, если у нас много компонентов, - довольно трудоемко. Еще более трудоемко потом менять значение этой директивы, если, к примеру, название или путь файла layout изменится.
В этом случае мы можем сгруппировать необходимые компоненты по папкам и на уровне папки применить ко всем компонентам одной папки определенную компоновку. Например, пусть у нас будет проект
со следующей структурой:
В папке Components/Layout файлы компонентов, которые определяют компоновку. Одна группа компонентов располагается в папке Components/Main,
а другая группа - в папке Components/Secondary. Допустим, ко всем компонентам в Components/Secondary мы хотим применить компоновку SecondLayout.
Для этого в эту папку добавляем файл _Imports.razor, в котором прописываем директиву @layout
:
@layout BlazorApp.Components.Layouts.SecondLayout
В итоге данная директива будет автоматически добавляться в каждый компонент в папке Components/Secondary.