ํ์คํ 8.0์ ๊ธฐ๋ณธ Blazor ํ
ํ๋ฆฟ์ผ๋ก๋ ์ ์ ์๋์ด ๋์ง ์๋ค์.
์ฌํ๊ฒ๋, ๊ธฐ๋ณธ css ์กฐ์ฐจ๋ ๋จน์ง ์์์.
css ๊ฒฉ๋ฆฌ ๋๋ถ์ธ์ง, Bootstrap ์คํ์ผ๋ ๋จนํต!
์๋ ๊ธฐ์กด Blazor Server Template์,
Package ์ถ๊ฐ๋ง ํด๋ ๋ฒํผ์ด ์๋ ํ๊ฑฐ๋ ์.
(js import ์กฐ์ฐจ ํ์ง ์์๋ ๊ฐ๋ฅํฉ๋๋ค. ์ด์ ๋ฒ์ ํจํค์ง์์ ์
๊ทธ๋ ์ด๋ ํ ๊ฒฝ์ฐ js ๋ฐฐ๋ฌ ์ต์
์ ๋๋ผ๋ ๊ถ์ฅ์ด ์์ด์.)
์๋ฌด๋๋ Blazor App ์์ฒด์ ๊ตฌ์กฐ๊ฐ ์ด์ง ๋ฐ๋์ด์ ์๊ธด ์์ธ์ด ์๋๊น ์ถ์๋ฐ์,
๊ธฐ์กด Blazor Server์ ๊ฒฝ์ฐ
์ง์
์ ์ธ Program.cs์์,
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
// ์ดํ์๋ต...
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
์ฌ๊ธฐ๋ฅผ ํตํด
_Host.cshtml โ App.razor ์ธ์คํด์ค ํ์ฑํ โ RouteView(์ธ์ฆ์ด ์์ผ๋ฉด AuthorizedRouteView๊ฐ ๋๊ฒ ์ฃ ?) โ
MainLayout.razor โ [RenderFragment?]
ํ์
์ธ @body
๋ก ๋ฉ์ธ ํ์ด์ง๋ฅผ ์ฒ์ ๊ฐ์ ธ์ค๋๋ฐ์.
8.0์์ ๊ธฐ๋ณธ ๊ตฌ์กฐ๊ฐ ๋ฐ๋์๋๋ผ๊ตฌ์.
์์ ์ฒ์์ Program.cs
builder.Services.AddRazorComponents()
.AddServerComponents();
...
app.MapRazorComponents<App>()
.AddServerRenderMode();
์ด๋ฏธ ์ฌ๊ธฐ์๋ถํฐ ๋ชจ์์ด ์ด์ง ๋ฌ๋ผ์ก์ง์?
๊ทผ๋ฐ ์ด์ ํธ์ถ ๋ฐ๋ผ๊ฐ๋ณด๋ฉด
App.razor ๋ถํฐ ๋ด์ฉ์ด ํ ๋ฌ๋ผ์ง๋๋ค.
//- 8.0์ App.razor
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<base href="/" />
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="BlazorApp1.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet />
</head>
<body>
<Routes /> // <- ์ฌ๊ธธ ์ ๋ด์ฃผ์ธ์!
<script src="_framework/blazor.web.js"></script>
</body>
</html>
///- ๊ธฐ์กด์ App.razor
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
๋ถ๋ช ๋ค๋ฅธ๋ฐ ์ต์ํ ์ด ๋๋์,
์ฌ์ค 8.0์ ์ ๊ตฌ์กฐ๋
_Host.cshtml์ ์๋ ๋ด์ฉ๊ณผ ๋งค์ฐ ํก์ฌํฉ๋๋ค.
//_Host.cshtml
@page "/"
@using Microsoft.AspNetCore.Components.Web
@namespace BlazorApp2.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="BlazorApp2.styles.css" rel="stylesheet" />
<link rel="icon" type="image/png" href="favicon.png"/>
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
<component type="typeof(App)" render-mode="ServerPrerendered" />
<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>
ํ๋ฐ 8.0 ํ
ํ๋ฆฟ์๋ Route.razor๊ฐ ์์ง์.
๋ง์ ๊ธฐ์กด App.razor์ ๋ด์ฉ์ด ์ฌ๊ธฐ ๋ค์ด๊ฐ์์ต๋๋ค.
//Route.razor
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
</Router>
์ฌ์ง์ด, MainLayout์ @body
๊ฐ ์๋ค์.
///MainLayout.razor
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">๐</a>
</div>
๊ทธ๋ ๋ค๋ฉด,
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
Program.cs->_Host.cshtml โ App.razor ์ธ์คํด์ค ํ์ฑํ โ RouteView(์ธ์ฆ์ด ์์ผ๋ฉด AuthorizedRouteView๊ฐ ๋๊ฒ ์ฃ ?) โ
MainLayout.razor โ @body
๊ตฌ์กฐ์์
app.MapRazorComponents<App>()
.AddServerRenderMode();
Program.cs โ App.razor โ Routes.razor โ MainLayout.razor โ @body
๋ก ๋ฐ๋๊ฑธ๋ก ์ ๋ฆฌ ํ ์ ์๊ฒ ์ต๋๋คโฆ๋ง
์ฌ๊ธฐ์ ์ ๊ฐ ๋ญ๊ฐ ๋ฌธ์ ์ธ์ง ์ ๋ชจ๋ฅด๊ฒ ๋๋ผ๊ณ ์.
์ฌ๊ธฐ์๋ถํฐ ์ ๊ฐ ํด๋ณธ ์๋์ธ๋ฐ,
ํน์๋ ํด์, 8.0์ Header ํ๊ทธ๋ฅผ ์์ฑํด์ฃผ๋ App.razor์๋ค๊ฐ
<script type="module" src="https://cdn.jsdelivr.net/npm/@fluentui/web-components/dist/web-components.min.js"></script>
์ ์ถ๊ฐํ๋๋, ๊ทธ์ ์์ผ ๋น์ฃผ์ผ์ ์ธ ๋ถ๋ถ๋ง ์๋ํ๋๋ผ๊ณ ์. Hover ํจ๊ณผ ๋ฑ๋ฑ, css๋ถ๋ถ๋ง์!
์ฌ์ง์ด eventHandler๋ฅผ ๋ถ์ฌ๋ ๋จนํต์ธ ์ฆ์์ด ใ
ใ
ํน์ ServerRender์ ๊ด๋ จ์ด ์๋ ๊ฑด๊ฐ?
๋ผ๊ณ ์๊ฐ ํ๋๋ฐ, 8.0๋ถํฐ(์ธ ์ง๋ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค๋งโฆ)๋ prerendered๊ฐ ๊ธฐ๋ณธ๊ฐ์ด๋๊ตฐ์.
@attribute [RenderModeAuto(prerender:true)]