為單一@page 掛上專用的 CSS 或 JavaScript |HeadOutlet & SectionOutlet
引言
有時有些 @page 須要專用 CSS 或 JavaScript。這時可用 HeadOutlet
\HeadContent
或 SectionOutlet
\SectionContent
來滿足需求。這技巧在 MVC 也有,稱做 @RenderSection。
參考文章
關鍵知識
有時有些 @page 須要專用 CSS 或 JavaScript。這時可用 HeadOutlet
\HeadContent
或 SectionOutlet
\SectionContent
來滿足需求。這技巧在 MVC 也有,稱做 @RenderSection。
其實 <PageTitle>
就是用 <HeadOutlet />
實作的。
開發環境
平台: .NET8
框架: Blazor Server App
關鍵原碼
@using Microsoft.AspNetCore.Components.Sections
<!DOCTYPE html>
<html lang="zh-hant">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="YourN8BlazorApp.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet @rendermode="@RenderModeForPage" />
<SectionOutlet @rendermode="@RenderModeForPage" SectionName="myHeadScript" />
<!-- 用 SectionOutlet 挖個洞 -->
</head>
<body>
<Routes @rendermode="@RenderModeForPage" />
<script src="_framework/blazor.web.js"></script>
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
</body>
</html>
@code {
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
private IComponentRenderMode? RenderModeForPage => HttpContext.Request.Path.StartsWithSegments("/Account")
? null
: InteractiveServer;
}
為該 @page 加入專用的 JavaScript,此例為 Login Page 專門加掛 Tailwind CSS 。
參考:https://flowbite.com/blocks/marketing/login/
@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Authentication.Cookies
@using Microsoft.AspNetCore.Authentication
@using System.Security.Claims
@using Microsoft.AspNetCore.Components.Sections
@using N8BlazorServerAuth.Services
@page "/Account/Login"
@inject NavigationManager navSvc
@inject ILogger<Login> Logger
@inject AccountService accSvc
<PageTitle>Log in</PageTitle>
<SectionContent SectionName="myHeadScript">
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
darkMode: 'class',
...略...
}
</script>
</SectionContent>
<!-- 該 Login Page 改專用 Tailwind CSS 來實作UI -->
<section class="bg-gray-50 dark:bg-gray-900">
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0">
<a href="#" class="flex items-center mb-6 text-2xl font-semibold text-gray-900 dark:text-white">
<img class="w-8 h-8 mr-2" src="https://flowbite.s3.amazonaws.com/blocks/marketing-ui/logo.svg" alt="logo">
Flowbite
</a>
<div class="w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700">
<div class="p-6 space-y-4 md:space-y-6 sm:p-8">
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
Sign in to your account
</h1>
<form class="space-y-4 md:space-y-6" action="#">
<div>
<label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Your email</label>
<input type="email" name="email" id="email" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="name@company.com" required="">
</div>
<div>
<label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Password</label>
<input type="password" name="password" id="password" placeholder="••••••••" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required="">
</div>
<div class="flex items-center justify-between">
<div class="flex items-start">
<div class="flex items-center h-5">
<input id="remember" aria-describedby="remember" type="checkbox" class="w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-primary-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-primary-600 dark:ring-offset-gray-800" required="">
</div>
<div class="ml-3 text-sm">
<label for="remember" class="text-gray-500 dark:text-gray-300">Remember me</label>
</div>
</div>
<a href="#" class="text-sm font-medium text-primary-600 hover:underline dark:text-primary-500">Forgot password?</a>
</div>
<button type="submit" class="w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">Sign in</button>
<p class="text-sm font-light text-gray-500 dark:text-gray-400">
Don’t have an account yet? <a href="#" class="font-medium text-primary-600 hover:underline dark:text-primary-500">Sign up</a>
</p>
</form>
</div>
</div>
</div>
</section>
@code {
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
[SupplyParameterFromForm]
private InputModel Input { get; set; } = new();
[SupplyParameterFromQuery]
private string? ReturnUrl { get; set; }
string? errorMessage;
[...略...]
public async Task LoginUser()
{
errorMessage = null;
var authUser = accSvc.Authenticate(Input);
if (authUser == null)
[...略...]
}
}
(EOF)
Last updated