ASP.NET Core Razor-komponenter
Notera
Det här är inte den senaste versionen av den här artikeln. För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln.
Varning
Den här versionen av ASP.NET Core stöds inte längre. Mer information finns i .NET och .NET Core Support Policy. För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln.
Viktig
Den här informationen gäller en förhandsversionsprodukt som kan ändras avsevärt innan den släpps kommersiellt. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, med avseende på den information som tillhandahålls här.
För den nuvarande utgåvan, se .NET 9-versionen av den här artikeln.
Den här artikeln beskriver hur du skapar och använder Razor komponenter i Blazor appar, inklusive vägledning om Razor syntax, namngivning av komponenter, namnområden och komponentparametrar.
Razor komponenter
Blazor appar skapas med hjälp av Razor komponenter, som informellt kallas Blazor komponenter eller endast komponenter. En komponent är en fristående del av användargränssnittet (UI) med bearbetningslogik för att aktivera dynamiskt beteende. Komponenter kan kapslas, återanvändas, delas mellan projekt och användas i MVC- och Razor Pages-appar.
Komponenter återges i en minnesrepresentation av webbläsarens Document Object Model (DOM) som kallas ett renderingsträd, vilket används för att uppdatera användargränssnittet på ett flexibelt och effektivt sätt.
Även om "Razor-komponenter" delar viss namngivning med andra ASP.NET Core-tekniker för innehållsrendering, måste Razor-komponenter skiljas från följande olika funktioner i ASP.NET Core:
- Razor vyer, som är Razor-baserade märkningssidor för MVC-appar.
- Visa komponenter, som är avsedda för återgivning av innehållssegment i stället för hela svar i Razor Pages- och MVC-appar.
Viktig
När du använder en Blazor Web Appkräver de flesta Blazor dokumentationsexempelkomponenter interaktivitet för att fungera och demonstrera de begrepp som beskrivs i artiklarna. När du testar en exempelkomponent som tillhandahålls av en artikel kontrollerar du att appen antingen använder global interaktivitet eller att komponenten använder ett interaktivt återgivningsläge. Mer information om det här ämnet finns i ASP.NET Core Blazor återgivningslägen, vilket är nästa artikel i innehållsförteckningen efter den här artikeln.
Komponentklasser
Komponenter implementeras med hjälp av en kombination av C# och HTML-kod i Razor komponentfiler med filtillägget .razor
.
ComponentBase är basklassen för komponenter som beskrivs av Razor komponentfiler. ComponentBase implementerar den lägsta abstraktionen av komponenter, IComponent-gränssnittet. ComponentBase definierar komponentegenskaper och -metoder för grundläggande funktioner, till exempel för att bearbeta en uppsättning inbyggda livscykelhändelser för komponenter.
ComponentBase
i dotnet/aspnetcore
referenskälla: Referenskällan innehåller ytterligare kommentarer om de inbyggda livscykelhändelserna. Tänk dock på att de interna implementeringarna av komponentfunktioner kan komma att ändras när som helst utan föregående meddelande.
Notera
Dokumentationslänkar till .NET-referenskällan läser vanligtvis in lagringsplatsens standardgren, vilket representerar den aktuella utvecklingen för nästa version av .NET. Om du vill välja en tagg för en specifik version använder du listrutan Växla grenar eller taggar. Mer information finns i Så här väljer du en versionstagg för ASP.NET Core-källkod (dotnet/AspNetCore.Docs #26205).
Utvecklare skapar vanligtvis Razor komponenter från Razor komponentfiler (.razor
) eller baserar sina komponenter på ComponentBase, men komponenter kan också skapas genom att implementera IComponent. Utvecklarbyggda komponenter som implementerar IComponent kan ta kontroll över rendering på låg nivå på bekostnad av att behöva utlösa rendering manuellt med händelser och livscykelmetoder som utvecklaren måste skapa och underhålla.
Ytterligare konventioner som antagits av Blazor dokumentationsexempelkod och exempelappar finns i grunderna ASP.NET Core Blazor.
Razor syntax
Komponenter använder Razor syntax. Två Razor funktioner används i stor utsträckning av komponenter, direktiv och direktivattribut. Det här är reserverade nyckelord med prefixet @
som visas i Razor markup.
Direktiv: Ändra hur komponentmarkeringen kompileras eller fungerar. Till exempel anger
@page
-direktivet en dirigerbar komponent med en routningsmall som kan nås direkt av en användares begäran i webbläsaren på en specifik URL.Enligt konventionen placeras en komponents direktiv högst upp i en komponentdefinition (
.razor
fil) i en konsekvent ordning. För upprepade direktiv placeras direktiven alfabetiskt efter namnområde eller typ, förutom@using
direktiv, som har särskild ordning på andra nivån.Följande ordning tillämpas på Blazor exempelappar och dokumentation. Komponenter som tillhandahålls av en Blazor projektmall kan skilja sig från följande ordning och använda ett annat format. Till exempel innehåller Blazor ramverk Identity komponenter tomma linjer mellan block av
@using
direktiv och block av@inject
direktiv. Du kan använda ett anpassat ordningsschema och format i dina egna appar.Dokumentation och exempel på app Razor direktivordning:
@page
-
@rendermode
(.NET 8 eller senare) @using
-
System
namnområden (alfabetisk ordning) -
Microsoft
namnområden (alfabetisk ordning) - Api-namnområden från tredje part (alfabetisk ordning)
- Appnamnområden (alfabetisk ordning)
-
- Andra direktiv (alfabetisk ordning)
Det finns inga tomma rader bland direktiven. En tom rad visas mellan direktiven och den första raden i Razor markering.
Exempel:
@page "/doctor-who-episodes/{season:int}" @rendermode InteractiveWebAssembly @using System.Globalization @using System.Text.Json @using Microsoft.AspNetCore.Localization @using Mandrill @using BlazorSample.Components.Layout @attribute [Authorize] @implements IAsyncDisposable @inject IJSRuntime JS @inject ILogger<DoctorWhoEpisodes> Logger <PageTitle>Doctor Who Episode List</PageTitle> ...
-direktivattribut: Ändra hur ett komponentelement kompileras eller fungerar.
Exempel:
<input @bind="episodeId" />
Du kan prefixa attributvärden med at-symbolen (
@
) för icke-explicita Razor uttryck (@bind="@episodeId"
), men vi rekommenderar det inte, och dokumenten använder inte metoden i exemplen.
Direktiv och direktivattribut som används i komponenter beskrivs ytterligare i den här artikeln och andra artiklar i Blazor dokumentationsuppsättning. Allmän information om Razor syntax finns i Razor syntaxreferens för ASP.NET Core.
Komponentnamn, klassnamn och namnområde
En komponents namn måste börja med ett versalt tecken:
✔️ stöds:ProductDetail.razor
stöds inte:productDetail.razor
Vanliga Blazor namngivningskonventioner som används i hela Blazor dokumentationen är:
- Filsökvägar och filnamn använder Pascal-case och visas före kodexemplen. Om en sökväg finns anger den den typiska mappplatsen.
Components/Pages/ProductDetail.razor
anger till exempel att komponentenProductDetail
har filnamnetProductDetail.razor
och finns i mappenPages
i mappenComponents
i appen. - Komponentfilvägar för routbara komponenter matchar deras URL:er i kebab-stil, vilket innebär att bindestreck används mellan orden i en komponents routemall. Till exempel begärs en komponent
ProductDetail
med routemallen/product-detail
(@page "/product-detail"
) i en webbläsare på den relativa URL:en/product-detail
.
†Pascal case (upper camel case) är en namngivningskonvention utan blanksteg och skiljetecken och med den första bokstaven i varje ord med versaler, inklusive det första ordet.
‡Kebab case är en namngivningskonvention utan mellanslag och skiljetecken som använder gemener och bindestreck mellan ord.
Komponenter är vanliga C#-klasser och kan placeras var som helst i ett projekt. Komponenter som producerar webbsidor finns vanligtvis i mappen Components/Pages
. Icke-sidkomponenter placeras ofta i mappen Components
eller en anpassad mapp som läggs till i projektet.
Vanligtvis härleds en komponents namnområde från appens rotnamnområde och komponentens plats (mapp) i appen. Om appens rotnamnområde är BlazorSample
och komponenten Counter
finns i mappen Components/Pages
:
-
Counter
-komponentens namnområde ärBlazorSample.Components.Pages
. - Komponentens fullständigt kvalificerade typnamn är
BlazorSample.Components.Pages.Counter
.
För anpassade mappar som innehåller komponenter lägger du till ett @using
-direktiv i den överordnade komponenten eller i appens _Imports.razor
-fil. I följande exempel blir komponenterna i mappen AdminComponents
tillgängliga:
@using BlazorSample.AdminComponents
Notera
@using
direktiv i _Imports.razor
-filen tillämpas endast på Razor filer (.razor
), inte C#-filer (.cs
).
Aliaserade using
-instruktioner stöds. I följande exempel görs den offentliga WeatherForecast
-klassen för komponenten GridRendering
tillgänglig som WeatherForecast
i en komponent någon annanstans i appen:
@using WeatherForecast = Components.Pages.GridRendering.WeatherForecast
Komponenter kan också refereras med hjälp av deras fullständigt kvalificerade namn, vilket inte kräver ett @using
direktiv. Följande exempel refererar direkt till komponenten ProductDetail
i mappen AdminComponents/Pages
i appen:
<BlazorSample.AdminComponents.Pages.ProductDetail />
Namnområdet för en komponent som har skapats med Razor baseras på följande (i prioritetsordning):
-
@namespace
-direktivet i Razor-filens markering (till exempel@namespace BlazorSample.CustomNamespace
). - Projektets
RootNamespace
i projektfilen (till exempel<RootNamespace>BlazorSample</RootNamespace>
). - Projektnamnområdet och sökvägen från projektroten till komponenten. Ramverket löser till exempel
{PROJECT NAMESPACE}/Components/Pages/Home.razor
med ett projektnamnområde medBlazorSample
till namnområdetBlazorSample.Components.Pages
för komponentenHome
.{PROJECT NAMESPACE}
är projektnamnområdet. Komponenter följer C#-namnbindningsregler. För komponentenHome
i det här exemplet är komponenterna inom omfattningen samtliga komponenter.- I samma mapp
Components/Pages
. - Komponenterna i projektets rot som inte uttryckligen anger ett annat namnområde.
- I samma mapp
Följande är inte stödjade:
-
global::
-kvalificeringen. - Delvis kvalificerade namn. Du kan till exempel inte lägga till
@using BlazorSample.Components
till en komponent och sedan referera till komponentenNavMenu
i appensComponents/Layout
mapp (Components/Layout/NavMenu.razor
) med<Layout.NavMenu></Layout.NavMenu>
.
En komponents namn måste börja med ett versalt tecken:
✔️ stöds:ProductDetail.razor
stöds inte:productDetail.razor
Vanliga Blazor namngivningskonventioner som används i hela Blazor dokumentationen är:
- Filsökvägar och filnamn använder Pascal-case och visas före kodexemplen. Om en sökväg finns anger den den typiska mappplatsen.
Pages/ProductDetail.razor
anger till exempel att komponentenProductDetail
har filnamnetProductDetail.razor
och finns i appensPages
mapp. - Komponentfilvägar för routbara komponenter matchar deras URL:er i kebab-stil, vilket innebär att bindestreck används mellan orden i en komponents routemall. Till exempel begärs en komponent
ProductDetail
med routemallen/product-detail
(@page "/product-detail"
) i en webbläsare på den relativa URL:en/product-detail
.
†Pascal case (upper camel case) är en namngivningskonvention utan blanksteg och skiljetecken och med den första bokstaven i varje ord med versaler, inklusive det första ordet.
‡Kebab case är en namngivningskonvention utan mellanslag och skiljetecken som använder gemener och bindestreck mellan ord.
Komponenter är vanliga C#-klasser och kan placeras var som helst i ett projekt. Komponenter som producerar webbsidor finns vanligtvis i mappen Pages
. Icke-sidkomponenter placeras ofta i mappen Shared
eller en anpassad mapp som läggs till i projektet.
Vanligtvis härleds en komponents namnområde från appens rotnamnområde och komponentens plats (mapp) i appen. Om appens rotnamnområde är BlazorSample
och komponenten Counter
finns i mappen Pages
:
-
Counter
-komponentens namnområde ärBlazorSample.Pages
. - Komponentens fullständigt kvalificerade typnamn är
BlazorSample.Pages.Counter
.
För anpassade mappar som innehåller komponenter lägger du till ett @using
-direktiv i den överordnade komponenten eller i appens _Imports.razor
-fil. I följande exempel blir komponenterna i mappen AdminComponents
tillgängliga:
@using BlazorSample.AdminComponents
Notera
@using
direktiv i _Imports.razor
-filen tillämpas endast på Razor filer (.razor
), inte C#-filer (.cs
).
Aliaserade using
-instruktioner stöds. I följande exempel görs den offentliga WeatherForecast
-klassen för komponenten GridRendering
tillgänglig som WeatherForecast
i en komponent någon annanstans i appen:
@using WeatherForecast = Pages.GridRendering.WeatherForecast
Komponenter kan också refereras med hjälp av deras fullständigt kvalificerade namn, vilket inte kräver ett @using
direktiv. Följande exempel refererar direkt till komponenten ProductDetail
i mappen Components
i appen:
<BlazorSample.Components.ProductDetail />
Namnområdet för en komponent som har skapats med Razor baseras på följande (i prioritetsordning):
-
@namespace
-direktivet i Razor-filens markering (till exempel@namespace BlazorSample.CustomNamespace
). - Projektets
RootNamespace
i projektfilen (till exempel<RootNamespace>BlazorSample</RootNamespace>
). - Projektnamnområdet och sökvägen från projektroten till komponenten. Ramverket löser till exempel
{PROJECT NAMESPACE}/Pages/Index.razor
med ett projektnamnområde medBlazorSample
till namnområdetBlazorSample.Pages
för komponentenIndex
.{PROJECT NAMESPACE}
är projektnamnområdet. Komponenter följer C#-namnbindningsregler. För komponentenIndex
i det här exemplet är komponenterna inom omfattningen samtliga komponenter.- I samma mapp
Pages
. - Komponenterna i projektets rot som inte uttryckligen anger ett annat namnområde.
- I samma mapp
Följande är inte stödjade:
-
global::
-kvalificeringen. - Delvis kvalificerade namn. Du kan till exempel inte lägga till
@using BlazorSample
till en komponent och sedan referera till komponentenNavMenu
i appensShared
mapp (Shared/NavMenu.razor
) med<Shared.NavMenu></Shared.NavMenu>
.
Stöd för partiell klass
Komponenter genereras som partiella C#-klasser och redigeras med någon av följande metoder:
- En enda fil innehåller C#-kod som definierats i en eller flera
@code
block, HTML-kod och Razor markering. Blazor projektmallar definierar sina komponenter med den här metoden med en fil. - HTML- och Razor-markering placeras i en Razor fil (
.razor
). C#-kod placeras i en kod bakom fil som definieras som en partiell klass (.cs
).
Notera
En komponentformatmall som definierar komponentspecifika formatmallar är en separat fil (.css
).
Blazor CSS-isolering beskrivs senare i ASP.NET Core Blazor CSS-isolering.
I följande exempel visas standardkomponenten Counter
med ett @code
block i en app som genererats från en Blazor projektmall. Markerings- och C#-kod finns i samma fil. Det här är den vanligaste metoden vid redigering av komponenter.
Counter.razor
:
@page "/counter"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount() => currentCount++;
}
@page "/counter"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount() => currentCount++;
}
@page "/counter"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
@page "/counter"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
Följande Counter
-komponent delar upp presentations-HTML och Razor-markup från C#-koden med hjälp av en kod-bakom-fil med en partiell klass. Att dela upp märkningen från C#-koden föredras av vissa organisationer och utvecklare för att organisera sin komponentkod så att det passar deras arbetssätt. Organisationens användargränssnittsexpert kan till exempel arbeta med presentationsskiktet oberoende av en annan utvecklare som arbetar med komponentens C#-logik. Metoden är också användbar när du arbetar med automatiskt genererad kod eller källgeneratorer. Mer information finns i partiella klasser och metoder (C#-programmeringsguide).
CounterPartialClass.razor
:
@page "/counter-partial-class"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@page "/counter-partial-class"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@page "/counter-partial-class"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@page "/counter-partial-class"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@page "/counter-partial-class"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@page "/counter-partial-class"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
CounterPartialClass.razor.cs
:
namespace BlazorSample.Components.Pages;
public partial class CounterPartialClass
{
private int currentCount = 0;
private void IncrementCount() => currentCount++;
}
namespace BlazorSample.Components.Pages;
public partial class CounterPartialClass
{
private int currentCount = 0;
private void IncrementCount() => currentCount++;
}
namespace BlazorSample.Pages;
public partial class CounterPartialClass
{
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
namespace BlazorSample.Pages
{
public partial class CounterPartialClass
{
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
}
@using
direktiv i _Imports.razor
-filen tillämpas endast på Razor filer (.razor
), inte C#-filer (.cs
). Lägg till namnområden i en partiell klassfil efter behov.
Vanliga namnområden som används av komponenter:
using System.Net.Http;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Sections
using Microsoft.AspNetCore.Components.Web;
using static Microsoft.AspNetCore.Components.Web.RenderMode;
using Microsoft.AspNetCore.Components.Web.Virtualization;
using Microsoft.JSInterop;
Vanliga namnområden inkluderar även namnområdet för appen och namnområdet som motsvarar appens Components
mapp:
using BlazorSample;
using BlazorSample.Components;
Ytterligare mappar kan också inkluderas, till exempel mappen Layout
:
using BlazorSample.Components.Layout;
using System.Net.Http;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.Web.Virtualization;
using Microsoft.JSInterop;
Vanliga namnområden inkluderar även namnområdet för appen och namnområdet som motsvarar appens Shared
mapp:
using BlazorSample;
using BlazorSample.Shared;
using System.Net.Http;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Components.Routing;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.JSInterop;
Vanliga namnområden inkluderar även namnområdet för appen och namnområdet som motsvarar appens Shared
mapp:
using BlazorSample;
using BlazorSample.Shared;
Ange en basklass
@inherits
-direktivet används för att ange en basklass för en komponent. Till skillnad från att använda partiella klasser, som bara delar markering från C#-logik, kan du med hjälp av en basklass ärva C#-kod för användning i en grupp med komponenter som delar basklassens egenskaper och metoder. Att använda basklasser minskar kodredundansen i appar och är användbara när du tillhandahåller baskod från klassbibliotek till flera appar. Mer information finns i Arv i C# och .NET.
I följande exempel härleds basklassen BlazorRocksBase1
från ComponentBase.
BlazorRocks1.razor
:
@page "/blazor-rocks-1"
@inherits BlazorRocksBase1
<PageTitle>Blazor Rocks!</PageTitle>
<h1>Blazor Rocks! Example 1</h1>
<p>
@BlazorRocksText
</p>
@page "/blazor-rocks-1"
@inherits BlazorRocksBase1
<PageTitle>Blazor Rocks!</PageTitle>
<h1>Blazor Rocks! Example 1</h1>
<p>
@BlazorRocksText
</p>
@page "/blazor-rocks-1"
@inherits BlazorRocksBase1
<PageTitle>Blazor Rocks!</PageTitle>
<h1>Blazor Rocks! Example 1</h1>
<p>
@BlazorRocksText
</p>
@page "/blazor-rocks-1"
@inherits BlazorRocksBase1
<PageTitle>Blazor Rocks!</PageTitle>
<h1>Blazor Rocks! Example 1</h1>
<p>
@BlazorRocksText
</p>
@page "/blazor-rocks-1"
@inherits BlazorRocksBase1
<h1>Blazor Rocks! Example 1</h1>
<p>
@BlazorRocksText
</p>
@page "/blazor-rocks-1"
@inherits BlazorRocksBase1
<h1>Blazor Rocks! Example 1</h1>
<p>
@BlazorRocksText
</p>
BlazorRocksBase1.cs
:
using Microsoft.AspNetCore.Components;
namespace BlazorSample;
public class BlazorRocksBase1 : ComponentBase
{
public string BlazorRocksText { get; set; } = "Blazor rocks the browser!";
}
using Microsoft.AspNetCore.Components;
namespace BlazorSample;
public class BlazorRocksBase1 : ComponentBase
{
public string BlazorRocksText { get; set; } = "Blazor rocks the browser!";
}
using Microsoft.AspNetCore.Components;
namespace BlazorSample;
public class BlazorRocksBase1 : ComponentBase
{
public string BlazorRocksText { get; set; } =
"Blazor rocks the browser!";
}
using Microsoft.AspNetCore.Components;
namespace BlazorSample;
public class BlazorRocksBase1 : ComponentBase
{
public string BlazorRocksText { get; set; } =
"Blazor rocks the browser!";
}
using Microsoft.AspNetCore.Components;
namespace BlazorSample;
public class BlazorRocksBase1 : ComponentBase
{
public string BlazorRocksText { get; set; } =
"Blazor rocks the browser!";
}
using Microsoft.AspNetCore.Components;
namespace BlazorSample;
public class BlazorRocksBase1 : ComponentBase
{
public string BlazorRocksText { get; set; } =
"Blazor rocks the browser!";
}
Routning
Routning i Blazor uppnås genom att tillhandahålla en routningsmall för varje tillgänglig komponent i appen med ett @page
direktiv. När en Razor fil med ett @page
-direktiv kompileras får den genererade klassen en RouteAttribute som anger routningsmallen. Vid körning söker routern efter komponentklasser med en RouteAttribute och återger den komponent som har en routningsmall som matchar den begärda URL:en.
Följande HelloWorld
komponent använder en vägmall med /hello-world
och den renderade webbsidan för komponenten nås på den relativa URL:en /hello-world
.
HelloWorld.razor
:
@page "/hello-world"
<PageTitle>Hello World!</PageTitle>
<h1>Hello World!</h1>
@page "/hello-world"
<PageTitle>Hello World!</PageTitle>
<h1>Hello World!</h1>
@page "/hello-world"
<h1>Hello World!</h1>
@page "/hello-world"
<h1>Hello World!</h1>
@page "/hello-world"
<h1>Hello World!</h1>
@page "/hello-world"
<h1>Hello World!</h1>
Den föregående komponenten läses in i webbläsaren på /hello-world
oavsett om du lägger till komponenten i appens användargränssnittsnavigering eller inte. Du kan också lägga till komponenter i komponenten NavMenu
så att en länk till komponenten visas i appens användargränssnittsbaserade navigering.
För den föregående HelloWorld
komponenten kan du lägga till en NavLink
komponent i komponenten NavMenu
. Mer information, inklusive beskrivningar av komponenterna NavLink
och NavMenu
finns i ASP.NET Core Blazor routning och navigering.
Markup
En komponents användargränssnitt definieras med hjälp av Razor syntax, som består av Razor markering, C#och HTML. När en app kompileras konverteras HTML-markerings- och C#-återgivningslogik till en komponentklass. Namnet på den genererade klassen matchar namnet på filen.
Medlemmar i komponentklassen definieras i ett eller flera @code
block. I @code
block anges komponenttillståndet och bearbetas med C#:
- Initialiserare för egenskaper och fält.
- Parametervärden från argument som skickas av överordnade komponenter och vägparametrar.
- Metoder för hantering av användarhändelser, livscykelhändelser och anpassad komponentlogik.
Komponentmedlemmar används i renderingslogik med C#-uttryck som börjar med symbolen @
. Till exempel renderas ett C#-fält genom att lägga till prefixet @
före fältnamnet. Följande Markup
komponent utvärderar och återger:
-
headingFontStyle
för CSS-egenskapsvärdetfont-style
för rubrikelementet. -
headingText
för innehållet i rubrikelementet.
Markup.razor
:
@page "/markup"
<PageTitle>Markup</PageTitle>
<h1>Markup Example</h1>
<h2 style="font-style:@headingFontStyle">@headingText</h2>
@code {
private string headingFontStyle = "italic";
private string headingText = "Put on your new Blazor!";
}
@page "/markup"
<PageTitle>Markup</PageTitle>
<h1>Markup Example</h1>
<h2 style="font-style:@headingFontStyle">@headingText</h2>
@code {
private string headingFontStyle = "italic";
private string headingText = "Put on your new Blazor!";
}
@page "/markup"
<h1 style="font-style:@headingFontStyle">@headingText</h1>
@code {
private string headingFontStyle = "italic";
private string headingText = "Put on your new Blazor!";
}
@page "/markup"
<h1 style="font-style:@headingFontStyle">@headingText</h1>
@code {
private string headingFontStyle = "italic";
private string headingText = "Put on your new Blazor!";
}
@page "/markup"
<h1 style="font-style:@headingFontStyle">@headingText</h1>
@code {
private string headingFontStyle = "italic";
private string headingText = "Put on your new Blazor!";
}
@page "/markup"
<h1 style="font-style:@headingFontStyle">@headingText</h1>
@code {
private string headingFontStyle = "italic";
private string headingText = "Put on your new Blazor!";
}
Notera
Exempel i dokumentationen för Blazor anger private
åtkomstmodifierare för privata medlemmar. Privata medlemmar är begränsade till en komponents klass. C# förutsätter dock åtkomstmodifieraren private
när ingen annan är angiven, så det är valfritt att uttryckligen ange medlemmar som "private
" i din egen kod. Mer information om åtkomstmodifierare finns i Access Modifiers (C# Programming Guide).
Det Blazor-ramverket bearbetar en komponent internt som ett -renderingsträd, vilket är kombinationen av en komponents DOM och CSSOM (Cascading Style Sheet Object Model). När komponenten först renderas, återskapas komponentens renderingsstruktur som svar på händelser. Blazor jämför det nya återgivningsträdet med föregående återgivningsträd och tillämpar eventuella ändringar på webbläsarens DOM för visning. För mer information, se ASP.NET Core Razor komponentåtergivning.
Razor syntax för C#-kontrollstrukturer, direktiv och direktivattribut är gemener (exempel: @if
, @code
, @bind
). Egenskapsnamn skrivs med versaler (exempel: @Body
för LayoutComponentBase.Body).
Asynkrona metoder (async
) stöder inte att returnera void
Det Blazor-ramverket spårar inte void
-returnerande asynkrona metoder (async
). Därför fångas inte undantag om void
returneras. Se alltid till att returnera en Task från asynkrona metoder.
Kapslade komponenter
Komponenter kan innehålla andra komponenter genom att deklarera dem med hjälp av HTML-syntax. Markeringen för att använda en komponent liknar en HTML-tagg där taggens namn är komponentens typ.
Överväg följande Heading
komponent, som kan användas av andra komponenter för att visa en rubrik.
Heading.razor
:
<h1 style="font-style:@headingFontStyle">Heading Example</h1>
@code {
private string headingFontStyle = "italic";
}
<h1 style="font-style:@headingFontStyle">Heading Example</h1>
@code {
private string headingFontStyle = "italic";
}
<h1 style="font-style:@headingFontStyle">Heading Example</h1>
@code {
private string headingFontStyle = "italic";
}
<h1 style="font-style:@headingFontStyle">Heading Example</h1>
@code {
private string headingFontStyle = "italic";
}
<h1 style="font-style:@headingFontStyle">Heading Example</h1>
@code {
private string headingFontStyle = "italic";
}
<h1 style="font-style:@headingFontStyle">Heading Example</h1>
@code {
private string headingFontStyle = "italic";
}
Följande markering i komponenten HeadingExample
återger den föregående Heading
komponenten på den plats där taggen <Heading />
visas.
HeadingExample.razor
:
@page "/heading-example"
<PageTitle>Heading</PageTitle>
<h1>Heading Example</h1>
<Heading />
@page "/heading-example"
<PageTitle>Heading</PageTitle>
<h1>Heading Example</h1>
<Heading />
@page "/heading-example"
<Heading />
@page "/heading-example"
<Heading />
@page "/heading-example"
<Heading />
@page "/heading-example"
<Heading />
Om en komponent innehåller ett HTML-element med en versal första bokstav som inte matchar ett komponentnamn inom samma namnområde genereras en varning som anger att elementet har ett oväntat namn. Om du lägger till ett @using
direktiv för komponentens namnområde blir komponenten tillgänglig, vilket löser varningen. Mer information finns i avsnittet Komponentnamn, klassnamn och namnområde.
Det Heading
komponentexemplet som visas i det här avsnittet har inget @page
direktiv, så Heading
komponenten är inte direkt tillgänglig för en användare via en direkt begäran i webbläsaren. Alla komponenter med ett @page
-direktiv kan dock kapslas i en annan komponent. Om Heading
komponenten var direkt åtkomlig genom att inkludera @page "/heading"
överst i filen Razor återges komponenten för webbläsarbegäranden på både /heading
och /heading-example
.
Komponentparametrar
Komponentparametrar skickar data till komponenter och definieras med hjälp av offentliga C#-egenskaper på komponentklassen med hjälp av attributet [Parameter]
.
I följande ParameterChild
komponent inkluderar komponentparametrarna:
Inbyggda referenstyper.
-
System.String överföra en rubrik i
Title
. -
System.Int32 för att skicka ett antal i
Count
.
-
System.String överföra en rubrik i
En användardefinierad referenstyp (
PanelBody
) för att överföra en Bootstrap-kortkropp iBody
.PanelBody.cs
:namespace BlazorSample; public class PanelBody { public string? Text { get; set; } public string? Style { get; set; } }
namespace BlazorSample; public class PanelBody { public string? Text { get; set; } public string? Style { get; set; } }
public class PanelBody { public string? Text { get; set; } public string? Style { get; set; } }
public class PanelBody { public string? Text { get; set; } public string? Style { get; set; } }
public class PanelBody { public string Text { get; set; } public string Style { get; set; } }
public class PanelBody { public string Text { get; set; } public string Style { get; set; } }
ParameterChild.razor
:
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style">
<p>@Body.Text</p>
@if (Count is not null)
{
<p>The count is @Count.</p>
}
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Set By Child";
[Parameter]
public PanelBody Body { get; set; } =
new()
{
Text = "Card content set by child.",
Style = "normal"
};
[Parameter]
public int? Count { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style">
<p>@Body.Text</p>
@if (Count is not null)
{
<p>The count is @Count.</p>
}
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Set By Child";
[Parameter]
public PanelBody Body { get; set; } =
new()
{
Text = "Card content set by child.",
Style = "normal"
};
[Parameter]
public int? Count { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style">
<p>@Body.Text</p>
@if (Count is not null)
{
<p>The count is @Count.</p>
}
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Set By Child";
[Parameter]
public PanelBody Body { get; set; } =
new()
{
Text = "Set by child.",
Style = "normal"
};
[Parameter]
public int? Count { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style">
<p>@Body.Text</p>
@if (Count is not null)
{
<p>The count is @Count.</p>
}
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Set By Child";
[Parameter]
public PanelBody Body { get; set; } =
new()
{
Text = "Set by child.",
Style = "normal"
};
[Parameter]
public int? Count { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style">
<p>@Body.Text</p>
@if (Count is not null)
{
<p>The count is @Count.</p>
}
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Set By Child";
[Parameter]
public PanelBody Body { get; set; } =
new()
{
Text = "Set by child.",
Style = "normal"
};
[Parameter]
public int? Count { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style">
<p>@Body.Text</p>
@if (Count is not null)
{
<p>The count is @Count.</p>
}
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Set By Child";
[Parameter]
public PanelBody Body { get; set; } =
new PanelBody()
{
Text = "Set by child.",
Style = "normal"
};
[Parameter]
public int? Count { get; set; }
}
Varning
Det finns stöd för att ange initiala värden för komponentparametrar, men skapa inte en komponent som skriver till sina egna parametrar när komponenten återges för första gången. Mer information finns i Undvik att skriva över parametrar i ASP.NET Core Blazor.
Komponentparametrarna för den ParameterChild
komponenten kan anges med argument i HTML-taggen som återger en instans av ParameterChild
komponenten. Följande överordnade komponent renderar två ParameterChild
komponenter:
- Den första
ParameterChild
komponenten återges utan att ange parameterargument. - Den andra
ParameterChild
-komponenten tar emot värden förTitle
ochBody
från den överordnade komponenten, som använder ett explicit C#-uttryck för att ange värdena förPanelBody
egenskaper.
Parameter1.razor
:
@page "/parameter-1"
<PageTitle>Parameter 1</PageTitle>
<h1>Parameter Example 1</h1>
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent"
Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
Parameter1.razor
:
@page "/parameter-1"
<PageTitle>Parameter 1</PageTitle>
<h1>Parameter Example 1</h1>
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent"
Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
ParameterParent.razor
:
@page "/parameter-parent"
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent"
Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
ParameterParent.razor
:
@page "/parameter-parent"
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent"
Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
ParameterParent.razor
:
@page "/parameter-parent"
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent"
Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
ParameterParent.razor
:
@page "/parameter-parent"
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent"
Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
Följande renderade HTML-kod från den överordnade komponenten visar standardvärden för ParameterChild
komponent när den överordnade komponenten inte anger komponentparametervärden. När den överordnade komponenten innehåller komponentparametervärden ersätter de standardvärdena för den ParameterChild
komponenten.
Notera
För tydlighetens skull visas de flesta av de renderade CSS-stilklasserna och vissa element inte i följande renderade HTML-kod. Huvudkonceptet som visas i följande exempel är att den överordnade komponenten tilldelade värden till den underordnade komponenten med hjälp av dess komponentparametrar.
<h1>Child component (without attribute values)</h1>
<div>Set By Child</div>
<div style="font-style:normal">
<p>Card content set by child.</p>
</div>
<h1>Child component (with attribute values)</h1>
<div>Set by Parent</div>
<div style="font-style:italic">
<p>Set by parent.</p>
</div>
Tilldela ett C#-fält, en egenskap eller ett resultat av en metod till en komponentparameter som ett HTML-attributvärde. Värdet för attributet kan vanligtvis vara valfritt C#-uttryck som matchar parametertypen. Värdet för attributet kan eventuellt börja med en reserverad symbol Razor@
, men det krävs inte.
Om komponentparametern är av typen sträng behandlas attributvärdet i stället som en C#-strängliteral. Om du vill ange ett C#-uttryck i stället använder du prefixet @
.
Följande överordnade komponent visar fyra instanser av den föregående ParameterChild
komponenten och anger deras Title
parametervärden till:
- Värdet för fältet
title
. - Resultatet av metoden
GetTitle
C#. - Det aktuella lokala datumet i långt format med ToLongDateString, som använder ett implicit C#-uttryck.
-
panelData
-objektets egenskapTitle
.
Den femte ParameterChild
komponentinstansen anger också parametern Count
. Observera hur en string
-typad parameter kräver ett @
prefix för att säkerställa att ett uttryck inte behandlas som en strängliteral. Emellertid är Count
ett heltal som kan vara null (System.Int32), så Count
kan ta emot värdet av count
utan ett @
prefix. Du kan upprätta en alternativ kodkonvention som kräver att utvecklare i din organisation alltid prefixar med @
. Hur som helst rekommenderar vi bara att du använder en konsekvent metod för hur komponentparametrar skickas i Razor markering.
Citattecken kring parameterattributvärden är valfria i de flesta fall enligt HTML5-specifikationen. Till exempel stöds Value=this
i stället för Value="this"
. Vi rekommenderar dock att du använder citattecken eftersom det är lättare att komma ihåg och allmänt använda i webbaserade tekniker.
I dokumentationen finns kodexempel:
- Använd alltid citattecken. Exempel:
Value="this"
. - Använd inte prefixet
@
med icke-literala tecken om det inte krävs. Exempel:Count="count"
, därcount
är en taltypsvariabel.Count="@count"
är en giltig stilistisk metod, men dokumentationen och exemplen antar inte konventionen. - Undvik alltid
@
när det gäller literaler, förutom inom Razor uttryck. Exempel:IsFixed="true"
. Detta inkluderar nyckelord (till exempelthis
) ochnull
, men du kan välja att använda dem om du vill. Till exempel ärIsFixed="@true"
ovanligt men stöds.
Parameter2.razor
:
@page "/parameter-2"
<PageTitle>Parameter 2</PageTitle>
<h1>Parameter Example 2</h1>
<ParameterChild Title="@title" />
<ParameterChild Title="@GetTitle()" />
<ParameterChild Title="@DateTime.Now.ToLongDateString()" />
<ParameterChild Title="@panelData.Title" />
<ParameterChild Title="String literal title" Count="count" />
@code {
private string title = "From Parent field";
private PanelData panelData = new();
private int count = 12345;
private string GetTitle() => "From Parent method";
private class PanelData
{
public string Title { get; set; } = "From Parent object";
}
}
Parameter2.razor
:
@page "/parameter-2"
<PageTitle>Parameter 2</PageTitle>
<h1>Parameter Example 2</h1>
<ParameterChild Title="@title" />
<ParameterChild Title="@GetTitle()" />
<ParameterChild Title="@DateTime.Now.ToLongDateString()" />
<ParameterChild Title="@panelData.Title" />
<ParameterChild Title="String literal title" Count="count" />
@code {
private string title = "From Parent field";
private PanelData panelData = new();
private int count = 12345;
private string GetTitle() => "From Parent method";
private class PanelData
{
public string Title { get; set; } = "From Parent object";
}
}
ParameterParent2.razor
:
@page "/parameter-parent-2"
<ParameterChild Title="@title" />
<ParameterChild Title="@GetTitle()" />
<ParameterChild Title="@DateTime.Now.ToLongDateString()" />
<ParameterChild Title="@panelData.Title" />
<ParameterChild Title="String literal title" Count="count" />
@code {
private string title = "From Parent field";
private PanelData panelData = new();
private int count = 12345;
private string GetTitle()
{
return "From Parent method";
}
private class PanelData
{
public string Title { get; set; } = "From Parent object";
}
}
ParameterParent2.razor
:
@page "/parameter-parent-2"
<ParameterChild Title="@title" />
<ParameterChild Title="@GetTitle()" />
<ParameterChild Title="@DateTime.Now.ToLongDateString()" />
<ParameterChild Title="@panelData.Title" />
<ParameterChild Title="String literal title" Count="count" />
@code {
private string title = "From Parent field";
private PanelData panelData = new();
private int count = 12345;
private string GetTitle()
{
return "From Parent method";
}
private class PanelData
{
public string Title { get; set; } = "From Parent object";
}
}
ParameterParent2.razor
:
@page "/parameter-parent-2"
<ParameterChild Title="@title" />
<ParameterChild Title="@GetTitle()" />
<ParameterChild Title="@DateTime.Now.ToLongDateString()" />
<ParameterChild Title="@panelData.Title" />
<ParameterChild Title="String literal title" Count="count" />
@code {
private string title = "From Parent field";
private PanelData panelData = new PanelData();
private int count = 12345;
private string GetTitle()
{
return "From Parent method";
}
private class PanelData
{
public string Title { get; set; } = "From Parent object";
}
}
Notera
När du tilldelar en C#-medlem till en komponentparameter ska du inte prefixa parameterns HTML-attribut med @
.
Rätt (Title
är en strängparameter, Count
är en numerisk parameter):
<ParameterChild Title="@title" Count="count" />
<ParameterChild Title="@title" Count="@count" />
Felaktig:
<ParameterChild @Title="@title" @Count="count" />
<ParameterChild @Title="@title" @Count="@count" />
Till skillnad från i Razor sidor (.cshtml
) kan Blazor inte utföra asynkront arbete i ett Razor uttryck när en komponent återges. Det beror på att Blazor är utformat för återgivning av interaktiva UIs. I ett interaktivt användargränssnitt måste skärmen alltid visa något, så det är inte meningsfullt att blockera återgivningsflödet. I stället utförs asynkront arbete under någon av de asynkrona livscykelhändelserna. Efter varje asynkron livscykelhändelse kan komponenten återges igen. Följande Razor syntax stöds inte :
<ParameterChild Title="await ..." />
<ParameterChild Title="@await ..." />
Koden i föregående exempel genererar ett kompilatorfel när appen skapas:
Operatorn "await" kan bara användas inom en asynkron metod. Överväg att markera den här metoden med modifieraren "async" och ändra dess returtyp till "Uppgift".
Om du vill hämta ett värde för parametern Title
i föregående exempel asynkront kan komponenten använda OnInitializedAsync
livscykelhändelse, vilket visas i följande exempel:
<ParameterChild Title="@title" />
@code {
private string? title;
protected override async Task OnInitializedAsync()
{
title = await ...;
}
}
Mer information finns i ASP.NET Core Razor-komponentens livscykel.
Användning av ett explicit Razor uttryck för att sammanfoga text med ett uttrycksresultat för tilldelning till en parameter inte stöds. Följande exempel syftar till att sammanfoga texten "Set by
" med ett objekts egenskapsvärde. Även om den här syntaxen stöds på en Razor-sida (.cshtml
) är den inte giltig för tilldelning till Title
-parametern för barnet i en komponent. Följande Razor syntax stöds inte :
<ParameterChild Title="Set by @(panelData.Title)" />
Koden i föregående exempel genererar ett kompilatorfel när appen skapas:
Komponentattribut stöder inte komplext innehåll (blandad C# och markering).
Om du vill stödja tilldelningen av ett sammansatt värde använder du en metod, ett fält eller en egenskap. I följande exempel utförs sammanfogningen av "Set by
" och ett objekts egenskapsvärde i C#-metoden GetTitle
:
Parameter3.razor
:
@page "/parameter-3"
<PageTitle>Parameter 3</PageTitle>
<h1>Parameter Example 3</h1>
<ParameterChild Title="@GetTitle()" />
@code {
private PanelData panelData = new();
private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData
{
public string Title { get; set; } = "Parent";
}
}
Parameter3.razor
:
@page "/parameter-3"
<PageTitle>Parameter 3</PageTitle>
<h1>Parameter Example 3</h1>
<ParameterChild Title="@GetTitle()" />
@code {
private PanelData panelData = new();
private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData
{
public string Title { get; set; } = "Parent";
}
}
ParameterParent3.razor
:
@page "/parameter-parent-3"
<ParameterChild Title="@GetTitle()" />
@code {
private PanelData panelData = new();
private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData
{
public string Title { get; set; } = "Parent";
}
}
ParameterParent3.razor
:
@page "/parameter-parent-3"
<ParameterChild Title="@GetTitle()" />
@code {
private PanelData panelData = new();
private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData
{
public string Title { get; set; } = "Parent";
}
}
ParameterParent3.razor
:
@page "/parameter-parent-3"
<ParameterChild Title="@GetTitle()" />
@code {
private PanelData panelData = new();
private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData
{
public string Title { get; set; } = "Parent";
}
}
ParameterParent3.razor
:
@page "/parameter-parent-3"
<ParameterChild Title="@GetTitle()" />
@code {
private PanelData panelData = new PanelData();
private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData
{
public string Title { get; set; } = "Parent";
}
}
Mer information finns i Razor syntaxreferens för ASP.NET Core.
Varning
Det finns stöd för att ange initiala värden för komponentparametrar, men skapa inte en komponent som skriver till sina egna parametrar när komponenten återges för första gången. Mer information finns i Undvik att skriva över parametrar i ASP.NET Core Blazor.
Komponentparametrar ska deklareras som automatiska egenskaper, vilket innebär att de inte ska innehålla anpassad logik i sina get
- eller set
-åtkomster. Följande StartData
egenskap är till exempel en automatisk egenskap:
[Parameter]
public DateTime StartData { get; set; }
Placera inte anpassad logik i get
- eller set
-accessorn eftersom komponentparametrar enbart är avsedda att användas som en kanal för en överordnad komponent för att flöda information till en underordnad komponent. Om en set
-accessor för en underordnad komponentegenskap innehåller logik som orsakar rerendering av den överordnade komponenten, resulterar en oändlig återgivningsloop.
Så här omvandlar du ett mottaget parametervärde:
- Lämna parameteregenskapen som en automatisk egenskap för att representera de angivna rådata.
- Skapa en annan egenskap eller metod för att ange transformerade data baserat på parameteregenskapen.
Åsidosätt OnParametersSetAsync
för att transformera en mottagen parameter varje gång nya data tas emot.
Det går att skriva ett initialt värde till en komponentparameter eftersom inledande värdetilldelningar inte stör Blazorautomatiska komponentåtergivning. Följande tilldelning av den aktuella lokala DateTime med DateTime.Now till StartData
är giltig syntax i en komponent:
[Parameter]
public DateTime StartData { get; set; } = DateTime.Now;
Efter den första tilldelningen av DateTime.Nowska du inte tilldela ett värde till StartData
i utvecklarkoden. Mer information finns i Undvik att skriva över parametrar i ASP.NET Core Blazor.
Använd attributet [EditorRequired]
för att ange en obligatorisk komponentparameter. Om ett parametervärde inte anges kan redigerare eller byggverktyg visa varningar för användaren. Det här attributet är endast giltigt för egenskaper som också har markerats med attributet [Parameter]
.
EditorRequiredAttribute framtvingas vid designtid samt när appen byggs. Attributet tillämpas inte vid körning och garanterar inte ett parametervärde som inte är lika mednull
.
[Parameter]
[EditorRequired]
public string? Title { get; set; }
Enradsattributlistor stöds också:
[Parameter, EditorRequired]
public string? Title { get; set; }
Använd inte required
modifieraren eller init
för komponentparameteregenskaper. Komponenter instansieras vanligtvis och tilldelas parametervärden med hjälp av reflektionsteknik, vilket kringgår de garantier som init
och required
är utformade för att säkerställa. Använd i stället attributet [EditorRequired]
för att ange en obligatorisk komponentparameter.
Använd inte init
-accessorn på komponentparameteregenskaper eftersom inställningen av komponentparametervärden med ParameterView.SetParameterProperties använder reflektion, vilket kringgår begränsningen för init-only-setter. Använd attributet [EditorRequired]
för att ange en obligatorisk komponentparameter.
Använd inte init
-accessorn på komponentparameteregenskaper eftersom inställningen av komponentparametervärden med ParameterView.SetParameterProperties använder reflektion, vilket kringgår begränsningen för init-only-setter.
Tuples
(API-dokumentation) stöds för komponentparametrar och RenderFragment
typer. Följande komponentparameterexempel skickar tre värden i Tuple
:
RenderTupleChild.razor
:
<div class="card w-50" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Tuple Card</div>
<div class="card-body">
<ul>
<li>Integer: @Data?.Item1</li>
<li>String: @Data?.Item2</li>
<li>Boolean: @Data?.Item3</li>
</ul>
</div>
</div>
@code {
[Parameter]
public (int, string, bool)? Data { get; set; }
}
RenderTupleParent.razor
:
@page "/render-tuple-parent"
<PageTitle>Render Tuple Parent</PageTitle>
<h1>Render Tuple Parent Example</h1>
<RenderTupleChild Data="data" />
@code {
private (int, string, bool) data = new(999, "I aim to misbehave.", true);
}
Namngivna tupplar stöds, enligt följande exempel:
NamedTupleChild.razor
:
<div class="card w-50" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Tuple Card</div>
<div class="card-body">
<ul>
<li>Integer: @Data?.TheInteger</li>
<li>String: @Data?.TheString</li>
<li>Boolean: @Data?.TheBoolean</li>
</ul>
</div>
</div>
@code {
[Parameter]
public (int TheInteger, string TheString, bool TheBoolean)? Data { get; set; }
}
NamedTuples.razor
:
@page "/named-tuples"
<PageTitle>Named Tuples</PageTitle>
<h1>Named Tuples Example</h1>
<NamedTupleChild Data="data" />
@code {
private (int TheInteger, string TheString, bool TheBoolean) data =
new(999, "I aim to misbehave.", true);
}
Citat ©2005 Universal Pictures: Serenity (Nathan Fillion)
Tuples
(API-dokumentation) stöds för komponentparametrar och RenderFragment
typer. Följande komponentparameterexempel skickar tre värden i Tuple
:
RenderTupleChild.razor
:
<div class="card w-50" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Tuple Card</div>
<div class="card-body">
<ul>
<li>Integer: @Data?.Item1</li>
<li>String: @Data?.Item2</li>
<li>Boolean: @Data?.Item3</li>
</ul>
</div>
</div>
@code {
[Parameter]
public (int, string, bool)? Data { get; set; }
}
RenderTupleParent.razor
:
@page "/render-tuple-parent"
<PageTitle>Render Tuple Parent</PageTitle>
<h1>Render Tuple Parent Example</h1>
<RenderTupleChild Data="data" />
@code {
private (int, string, bool) data = new(999, "I aim to misbehave.", true);
}
Namngivna tupplar stöds, enligt följande exempel:
NamedTupleChild.razor
:
<div class="card w-50" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Tuple Card</div>
<div class="card-body">
<ul>
<li>Integer: @Data?.TheInteger</li>
<li>String: @Data?.TheString</li>
<li>Boolean: @Data?.TheBoolean</li>
</ul>
</div>
</div>
@code {
[Parameter]
public (int TheInteger, string TheString, bool TheBoolean)? Data { get; set; }
}
NamedTuples.razor
:
@page "/named-tuples"
<PageTitle>Named Tuples</PageTitle>
<h1>Named Tuples Example</h1>
<NamedTupleChild Data="data" />
@code {
private (int TheInteger, string TheString, bool TheBoolean) data =
new(999, "I aim to misbehave.", true);
}
Citat ©2005 Universal Pictures: Serenity (Nathan Fillion)
Tuples
(API-dokumentation) stöds för komponentparametrar och RenderFragment
typer. Följande komponentparameterexempel skickar tre värden i Tuple
:
RenderTupleChild.razor
:
<div class="card w-50" style="margin-bottom:15px">
<div class="card-header font-weight-bold"><code>Tuple</code> Card</div>
<div class="card-body">
<ul>
<li>Integer: @Data?.Item1</li>
<li>String: @Data?.Item2</li>
<li>Boolean: @Data?.Item3</li>
</ul>
</div>
</div>
@code {
[Parameter]
public (int, string, bool)? Data { get; set; }
}
RenderTupleParent.razor
:
@page "/render-tuple-parent"
<h1>Render Tuple Parent</h1>
<RenderTupleChild Data="data" />
@code {
private (int, string, bool) data = new(999, "I aim to misbehave.", true);
}
Namngivna tupplar stöds, enligt följande exempel:
RenderNamedTupleChild.razor
:
<div class="card w-50" style="margin-bottom:15px">
<div class="card-header font-weight-bold"><code>Tuple</code> Card</div>
<div class="card-body">
<ul>
<li>Integer: @Data?.TheInteger</li>
<li>String: @Data?.TheString</li>
<li>Boolean: @Data?.TheBoolean</li>
</ul>
</div>
</div>
@code {
[Parameter]
public (int TheInteger, string TheString, bool TheBoolean)? Data { get; set; }
}
RenderNamedTupleParent.razor
:
@page "/render-named-tuple-parent"
<h1>Render Named Tuple Parent</h1>
<RenderNamedTupleChild Data="data" />
@code {
private (int TheInteger, string TheString, bool TheBoolean) data =
new(999, "I aim to misbehave.", true);
}
Citat ©2005 Universal Pictures: Serenity (Nathan Fillion)
Routningsparametrar
Komponenter kan ange routningsparametrar i vägmallen för @page
-direktivet. Den Blazor routern använder routningsparametrar för att fylla i motsvarande komponentparametrar.
RouteParameter1.razor
:
@page "/route-parameter-1/{text}"
<PageTitle>Route Parameter 1</PageTitle>
<h1>Route Parameter Example 1</h1>
<p>Blazor is @Text!</p>
@code {
[Parameter]
public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"
<PageTitle>Route Parameter 1</PageTitle>
<h1>Route Parameter Example 1</h1>
<p>Blazor is @Text!</p>
@code {
[Parameter]
public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"
<h1>Blazor is @Text!</h1>
@code {
[Parameter]
public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"
<h1>Blazor is @Text!</h1>
@code {
[Parameter]
public string? Text { get; set; }
}
@page "/route-parameter-1/{text}"
<h1>Blazor is @Text!</h1>
@code {
[Parameter]
public string Text { get; set; }
}
@page "/route-parameter-1/{text}"
<h1>Blazor is @Text!</h1>
@code {
[Parameter]
public string Text { get; set; }
}
Mer information finns i avsnittet Routeparametrar i ASP.NET Core Blazor routning och navigering. Valfria vägparametrar stöds också och beskrivs i samma avsnitt. Information om catch-all-ruttparametrar ({*pageRoute}
), som fångar upp sökvägar över flera mappgränser, finns i avsnittet Catch-all route parameters i ASP.NET Core Blazor ruttning och navigering.
Mer information finns i avsnittet Routeparametrar i ASP.NET Core Blazor routning och navigering. Valfria vägparametrar stöds inte, så två @page
-direktiv krävs (mer information finns i avsnittet Route-parametrar). Information om catch-all-ruttparametrar ({*pageRoute}
), som fångar upp sökvägar över flera mappgränser, finns i avsnittet Catch-all route parameters i ASP.NET Core Blazor ruttning och navigering.
Varning
Med komprimering, som är aktiverad som standard, undviker du att skapa säkra (autentiserade/auktoriserade) interaktiva komponenter på serversidan som återger data från ej betrodda källor. Ej betrodda källor omfattar routningsparametrar, frågesträngar, data från JS interop och alla andra datakällor som en användare från tredje part kan kontrollera (databaser, externa tjänster). Mer information finns i vägledningen för ASP.NET Core BlazorSignalR och vägledning för hotreducering för ASP.NET Core Blazor interaktiv server-sidesrendering.
Innehållsåtergivningsfragment för barn
Komponenter kan ange innehållet i en annan komponent. Tilldelningskomponenten innehåller innehållet mellan den underordnade komponentens inledande och avslutande taggar.
I följande exempel har komponenten RenderFragmentChild
en ChildContent
komponentparameter som representerar ett segment i användargränssnittet som ska återges som en RenderFragment. Positionen för ChildContent
i komponentens Razor markering är där innehållet återges i de slutliga HTML-utdata.
RenderFragmentChild.razor
:
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
Viktig
Egenskapen som tar emot RenderFragment innehåll måste namnges ChildContent
enligt konventionen.
Händelseåteranrop stöds inte för RenderFragment.
Följande komponent tillhandahåller innehåll för att rendera RenderFragmentChild
genom att placera innehållet mellan den underordnade komponentens inledande och avslutande taggar.
RenderFragments.razor
:
@page "/render-fragments"
<PageTitle>Render Fragments</PageTitle>
<h1>Render Fragments Example</h1>
<RenderFragmentChild>
Content of the child component is supplied
by the parent component.
</RenderFragmentChild>
RenderFragments.razor
:
@page "/render-fragments"
<PageTitle>Render Fragments</PageTitle>
<h1>Render Fragments Example</h1>
<RenderFragmentChild>
Content of the child component is supplied
by the parent component.
</RenderFragmentChild>
RenderFragmentParent.razor
:
@page "/render-fragment-parent"
<h1>Render child content</h1>
<RenderFragmentChild>
Content of the child component is supplied
by the parent component.
</RenderFragmentChild>
RenderFragmentParent.razor
:
@page "/render-fragment-parent"
<h1>Render child content</h1>
<RenderFragmentChild>
Content of the child component is supplied
by the parent component.
</RenderFragmentChild>
RenderFragmentParent.razor
:
@page "/render-fragment-parent"
<h1>Render child content</h1>
<RenderFragmentChild>
Content of the child component is supplied
by the parent component.
</RenderFragmentChild>
RenderFragmentParent.razor
:
@page "/render-fragment-parent"
<h1>Render child content</h1>
<RenderFragmentChild>
Content of the child component is supplied
by the parent component.
</RenderFragmentChild>
Återgivningsfragment används för att återge underordnat innehåll i Blazor appar och beskrivs med exempel i följande artiklar och artikelavsnitt:
Notera
Blazor ramverkets inbyggda Razor komponenter använder samma ChildContent
komponentparameterkonvention för att ange innehållet. Du kan se de komponenter som sätter barninnehåll genom att söka efter egenskapsnamnet för komponentparametern ChildContent
i API-dokumentationen (filtrera API:t med söktermen "ChildContent").
Rendera fragment för återanvändbar renderingslogik
Du kan räkna ut underordnade komponenter enbart som ett sätt att återanvända renderingslogik. I alla komponenters @code
block definierar du en RenderFragment och återger fragmentet från valfri plats så många gånger som behövs:
@RenderWelcomeInfo
<p>Render the welcome info a second time:</p>
@RenderWelcomeInfo
@code {
private RenderFragment RenderWelcomeInfo = @<p>Welcome to your new app!</p>;
}
Mer information finns i Återanvänd renderingslogik.
Loopvariabler med komponentparametrar och barninnehåll
Rendering av komponenter i en for
-loop kräver en lokal indexvariabel om den inkrementella loopvariabeln används av komponentens parametrar eller RenderFragment underordnat innehåll.
Tänk på följande komponent RenderFragmentChild2
som har både en komponentparameter (Id
) och ett renderfragment för att visa barninnehåll (ChildContent
).
RenderFragmentChild2.razor
:
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">Child content (@Id)</div>
<div class="card-body">@ChildContent</div>
</div>
@code {
[Parameter]
public string? Id { get; set; }
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
När du återger RenderFragmentChild2
komponenten i en överordnad komponent använder du en lokal indexvariabel (ct
i följande exempel) i stället för loopvariabeln (c
) när du tilldelar komponentparametervärdet och anger den underordnade komponentens innehåll:
@for (int c = 1; c < 4; c++)
{
var ct = c;
<RenderFragmentChild2 Id="@($"Child{ct}")">
Count: @ct
</RenderFragmentChild2>
}
Du kan också använda en foreach
-loop med Enumerable.Range i stället för en for
-loop:
@foreach (var c in Enumerable.Range(1, 3))
{
<RenderFragmentChild2 Id="@($"Child{c}")">
Count: @c
</RenderFragmentChild2>
}
Samla in referenser till komponenter
Komponentreferenser är ett sätt att referera till en komponentinstans för att utfärda kommandon. Så här avbildar du en komponentreferens:
- Lägg till attributet
@ref
till den underordnade komponenten. - Definiera ett fält av samma typ som den underordnade komponenten.
När komponenten återges fylls fältet i med komponentinstansen. Du kan sedan anropa .NET-metoder på instansen.
Tänk på följande ReferenceChild
komponent som loggar ett meddelande när dess ChildMethod
anropas.
ReferenceChild.razor
:
@inject ILogger<ReferenceChild> Logger
@if (value > 0)
{
<p>
<code>value</code>: @value
</p>
}
@code {
private int value;
public void ChildMethod(int value)
{
Logger.LogInformation("Received {Value} in ChildMethod", value);
this.value = value;
StateHasChanged();
}
}
@inject ILogger<ReferenceChild> Logger
@if (value > 0)
{
<p>
<code>value</code>: @value
</p>
}
@code {
private int value;
public void ChildMethod(int value)
{
Logger.LogInformation("Received {Value} in ChildMethod", value);
this.value = value;
StateHasChanged();
}
}
@using Microsoft.Extensions.Logging
@inject ILogger<ReferenceChild> Logger
@code {
public void ChildMethod(int value)
{
Logger.LogInformation("Received {Value} in ChildMethod", value);
}
}
@using Microsoft.Extensions.Logging
@inject ILogger<ReferenceChild> Logger
@code {
public void ChildMethod(int value)
{
Logger.LogInformation("Received {Value} in ChildMethod", value);
}
}
@using Microsoft.Extensions.Logging
@inject ILogger<ReferenceChild> Logger
@code {
public void ChildMethod(int value)
{
Logger.LogInformation("Received {Value} in ChildMethod", value);
}
}
@using Microsoft.Extensions.Logging
@inject ILogger<ReferenceChild> Logger
@code {
public void ChildMethod(int value)
{
Logger.LogInformation("Received {Value} in ChildMethod", value);
}
}
En komponentreferens fylls endast i efter att komponenten återges och dess utdata innehåller ReferenceChild
-element. Tills komponenten återges finns det inget att referera till. Försök inte anropa en refererad komponentmetod direkt till en händelsehanterare (till exempel @onclick="childComponent!.ChildMethod(5)"
) eftersom referensvariabeln kanske inte tilldelas när klickhändelsen tilldelas.
Om du vill ändra komponentreferenser när komponenten har slutfört återgivningen använder du metoderna OnAfterRender
eller OnAfterRenderAsync
.
I följande exempel används den föregående ReferenceChild
komponenten.
ReferenceParent.razor
:
@page "/reference-parent"
<div>
<button @onclick="@(() => childComponent1!.ChildMethod(5))">
Call <code>ReferenceChild.ChildMethod</code> (first instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent1" />
</div>
<div>
<button @onclick="CallChildMethod">
Call <code>ReferenceChild.ChildMethod</code> (second instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent2" />
</div>
@code {
private ReferenceChild? childComponent1;
private ReferenceChild? childComponent2;
private void CallChildMethod() => childComponent2!.ChildMethod(5);
}
@page "/reference-parent"
<div>
<button @onclick="@(() => childComponent1!.ChildMethod(5))">
Call <code>ReferenceChild.ChildMethod</code> (first instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent1" />
</div>
<div>
<button @onclick="CallChildMethod">
Call <code>ReferenceChild.ChildMethod</code> (second instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent2" />
</div>
@code {
private ReferenceChild? childComponent1;
private ReferenceChild? childComponent2;
private void CallChildMethod() => childComponent2!.ChildMethod(5);
}
@page "/reference-parent"
<div>
<button @onclick="@(() => childComponent1!.ChildMethod(5))">
Call <code>ReferenceChild.ChildMethod</code> (first instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent1" />
</div>
<div>
<button @onclick="CallChildMethod">
Call <code>ReferenceChild.ChildMethod</code> (second instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent2" />
</div>
@code {
private ReferenceChild? childComponent1;
private ReferenceChild? childComponent2;
private void CallChildMethod()
{
childComponent2!.ChildMethod(5);
}
}
@page "/reference-parent"
<div>
<button @onclick="@(() => childComponent1!.ChildMethod(5))">
Call <code>ReferenceChild.ChildMethod</code> (first instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent1" />
</div>
<div>
<button @onclick="CallChildMethod">
Call <code>ReferenceChild.ChildMethod</code> (second instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent2" />
</div>
@code {
private ReferenceChild? childComponent1;
private ReferenceChild? childComponent2;
private void CallChildMethod()
{
childComponent2!.ChildMethod(5);
}
}
@page "/reference-parent"
<div>
<button @onclick="@(() => childComponent1!.ChildMethod(5))">
Call <code>ReferenceChild.ChildMethod</code> (first instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent1" />
</div>
<div>
<button @onclick="CallChildMethod">
Call <code>ReferenceChild.ChildMethod</code> (second instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent2" />
</div>
@code {
private ReferenceChild childComponent1;
private ReferenceChild childComponent2;
private void CallChildMethod()
{
childComponent2!.ChildMethod(5);
}
}
@page "/reference-parent"
<div>
<button @onclick="@(() => childComponent1!.ChildMethod(5))">
Call <code>ReferenceChild.ChildMethod</code> (first instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent1" />
</div>
<div>
<button @onclick="CallChildMethod">
Call <code>ReferenceChild.ChildMethod</code> (second instance)
with an argument of 5
</button>
<ReferenceChild @ref="childComponent2" />
</div>
@code {
private ReferenceChild childComponent1;
private ReferenceChild childComponent2;
private void CallChildMethod()
{
childComponent2!.ChildMethod(5);
}
}
När du samlar in komponentreferenser använder du en liknande syntax för att att samla in elementreferenser, men att samla in komponentreferenser är inte en JavaScript-interop-funktion. Komponentreferenser skickas inte till JavaScript-kod. Komponentreferenser används endast i .NET-kod.
Viktig
Använd inte komponentreferenser för att ändra tillståndet hos barnkomponenter. Använd i stället normala deklarativa komponentparametrar för att skicka data till underordnade komponenter. Användning av komponentparametrar resulterar i underordnade komponenter som renderas om automatiskt vid rätt tidpunkter. Mer information finns i avsnittet komponentparametrar och artikeln ASP.NET Core Blazor databindning.
Använda ett attribut
Attribut kan tillämpas på komponenter med @attribute
-direktivet. I följande exempel tillämpas attributet [Authorize]
på komponentens klass:
@page "/"
@attribute [Authorize]
Villkorsstyrda HTML-elementattribut och DOM-egenskaper
Blazor antar följande allmänna beteenden:
- För HTML-attribut Blazor anger eller tar bort attributet villkorligt baserat på .NET-värdet. Om .NET-värdet är
false
ellernull
anges inte attributet eller tas bort om det angavs tidigare. - För DOM-egenskaper, till exempel
checked
ellervalue
anger Blazor DOM-egenskapen baserat på .NET-värdet. Om .NET-värdet ärfalse
ellernull
återställs DOM-egenskapen till ett standardvärde.
Vilka Razor syntaxattribut motsvarar HTML-attribut och vilka som motsvarar DOM-egenskaper förblir odokumenterade eftersom det här är en information om ramverksimplementering som kan ändras utan föregående meddelande.
Varning
Vissa HTML-attribut, till exempel aria-pressed
, måste ha ett strängvärde på antingen "true" eller "false". Eftersom de kräver ett strängvärde och inte ett booleskt värde måste du använda en .NET-string
och inte en bool
för deras värde. Detta är ett krav som anges av webbläsarens DOM-API:er.
Raw HTML
Strängar återges normalt med hjälp av DOM-textnoder, vilket innebär att alla markeringar som de kan innehålla ignoreras och behandlas som literaltext. Om du vill återge rå HTML omsluter du HTML-innehållet i ett MarkupString värde. Värdet parsas som HTML eller SVG och infogas i DOM.
Varning
Det är en säkerhetsrisk och bör alltid undvikas om du gör en opålitlig HTML-kod som skapats från en opålitlig källa.
I följande exempel visas hur du använder MarkupString typ för att lägga till ett block med statiskt HTML-innehåll i de renderade utdata för en komponent.
MarkupStrings.razor
:
@page "/markup-strings"
<PageTitle>Markup Strings</PageTitle>
<h1>Markup Strings Example</h1>
@((MarkupString)myMarkup)
@code {
private string myMarkup =
"<p class=\"text-danger\">This is a dangerous <em>markup string</em>.</p>";
}
MarkupStrings.razor
:
@page "/markup-strings"
<PageTitle>Markup Strings</PageTitle>
<h1>Markup Strings Example</h1>
@((MarkupString)myMarkup)
@code {
private string myMarkup =
"<p class=\"text-danger\">This is a dangerous <em>markup string</em>.</p>";
}
MarkupStringExample.razor
:
@page "/markup-string-example"
@((MarkupString)myMarkup)
@code {
private string myMarkup =
"<p class=\"text-danger\">This is a dangerous <em>markup string</em>.</p>";
}
MarkupStringExample.razor
:
@page "/markup-string-example"
@((MarkupString)myMarkup)
@code {
private string myMarkup =
"<p class=\"text-danger\">This is a dangerous <em>markup string</em>.</p>";
}
MarkupStringExample.razor
:
@page "/markup-string-example"
@((MarkupString)myMarkup)
@code {
private string myMarkup =
"<p class=\"text-danger\">This is a dangerous <em>markup string</em>.</p>";
}
MarkupStringExample.razor
:
@page "/markup-string-example"
@((MarkupString)myMarkup)
@code {
private string myMarkup =
"<p class=\"text-danger\">This is a dangerous <em>markup string</em>.</p>";
}
Razor mallar
Återgivningsfragment kan definieras med hjälp av Razor mallsyntax för att definiera ett gränssnittsfragment. Razor mallar använder följande format:
@<{HTML tag}>...</{HTML tag}>
I följande exempel visas hur du anger RenderFragment och RenderFragment<TValue> värden och renderar mallar direkt i en komponent. Återgivningsfragment kan också skickas som argument till mall-baserade komponenter.
RazorTemplate.razor
:
@page "/razor-template"
<PageTitle>Razor Template</PageTitle>
<h1>Razor Template Example</h1>
@timeTemplate
@petTemplate(new Pet { Name = "Nutty Rex" })
@code {
private RenderFragment timeTemplate = @<p>The time is @DateTime.Now.</p>;
private RenderFragment<Pet> petTemplate = (pet) => @<p>Pet: @pet.Name</p>;
private class Pet
{
public string? Name { get; set; }
}
}
@page "/razor-template"
<PageTitle>Razor Template</PageTitle>
<h1>Razor Template Example</h1>
@timeTemplate
@petTemplate(new Pet { Name = "Nutty Rex" })
@code {
private RenderFragment timeTemplate = @<p>The time is @DateTime.Now.</p>;
private RenderFragment<Pet> petTemplate = (pet) => @<p>Pet: @pet.Name</p>;
private class Pet
{
public string? Name { get; set; }
}
}
@page "/razor-template"
@timeTemplate
@petTemplate(new Pet { Name = "Nutty Rex" })
@code {
private RenderFragment timeTemplate = @<p>The time is @DateTime.Now.</p>;
private RenderFragment<Pet> petTemplate = (pet) => @<p>Pet: @pet.Name</p>;
private class Pet
{
public string? Name { get; set; }
}
}
@page "/razor-template"
@timeTemplate
@petTemplate(new Pet { Name = "Nutty Rex" })
@code {
private RenderFragment timeTemplate = @<p>The time is @DateTime.Now.</p>;
private RenderFragment<Pet> petTemplate = (pet) => @<p>Pet: @pet.Name</p>;
private class Pet
{
public string? Name { get; set; }
}
}
@page "/razor-template"
@timeTemplate
@petTemplate(new Pet { Name = "Nutty Rex" })
@code {
private RenderFragment timeTemplate = @<p>The time is @DateTime.Now.</p>;
private RenderFragment<Pet> petTemplate = (pet) => @<p>Pet: @pet.Name</p>;
private class Pet
{
public string Name { get; set; }
}
}
@page "/razor-template"
@timeTemplate
@petTemplate(new Pet { Name = "Nutty Rex" })
@code {
private RenderFragment timeTemplate = @<p>The time is @DateTime.Now.</p>;
private RenderFragment<Pet> petTemplate = (pet) => @<p>Pet: @pet.Name</p>;
private class Pet
{
public string Name { get; set; }
}
}
Renderade utdata från föregående kod:
<p>The time is 4/19/2021 8:54:46 AM.</p>
<p>Pet: Nutty Rex</p>
Statiska tillgångar
Blazor följer konventionen om ASP.NET Core-appar för statiska tillgångar. Statiska tillgångar finns i projektets mapp web root
(wwwroot
) eller mappar under mappen wwwroot
.
Använd en basrelativ sökväg (/
) för att referera till webbroten för en statisk resurs. I följande exempel finns logo.png
fysiskt i mappen {PROJECT ROOT}/wwwroot/images
.
{PROJECT ROOT}
är appens projektrot.
<img alt="Company logo" src="/images/logo.png" />
Komponenter stöder inte tilde-slash-notation (~/
).
Information om hur du anger en apps bassökväg finns i Host and deploy ASP.NET Core Blazor.
Tag Helpers stöds inte i komponenter
Tag Helpers
stöds inte i komponenter. Om du vill tillhandahålla Tag Helper-liknande funktioner i Blazorskapar du en komponent med samma funktioner som Tag Helper och använder komponenten i stället.
SVG-bilder (Scalable Vector Graphics)
Eftersom Blazor renderar HTML stöds bilder som stöds av webbläsare, inklusive SVG-bilder (Scalable Vector Graphics) (.svg
), via taggen <img>
:
<img alt="Example image" src="image.svg" />
På samma sätt stöds SVG-avbildningar i CSS-reglerna för en formatmallsfil (.css
):
.element-class {
background-image: url("image.svg");
}
Blazor stöder <foreignObject>
-elementet för att visa godtycklig HTML i en SVG. Märkspråket kan representera godtycklig HTML, RenderFragmenteller Razor-komponent.
Följande exempel visar:
- Visning av en
string
(@message
). - Dubbelriktad bindning med ett
<input>
-element och ettvalue
fält. - En
Robot
-komponent.
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" rx="10" ry="10" width="200" height="200" stroke="black"
fill="none" />
<foreignObject x="20" y="20" width="160" height="160">
<p>@message</p>
</foreignObject>
</svg>
<svg xmlns="http://www.w3.org/2000/svg">
<foreignObject width="200" height="200">
<label>
Two-way binding:
<input @bind="value" @bind:event="oninput" />
</label>
</foreignObject>
</svg>
<svg xmlns="http://www.w3.org/2000/svg">
<foreignObject>
<Robot />
</foreignObject>
</svg>
@code {
private string message = "Lorem ipsum dolor sit amet, consectetur adipiscing " +
"elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
private string? value;
}
Beteende för återgivning av tomt utrymme
Om inte @preservewhitespace
-direktivet används med värdet true
tas extra tomt utrymme bort om:
- Inledande eller avslutande inom ett element.
- Inledande eller avslutande i en RenderFragment/RenderFragment<TValue> parameter (till exempel underordnat innehåll som skickas till en annan komponent).
- Det föregår eller följer ett C#-kodblock, till exempel
@if
eller@foreach
.
Borttagning av tomt utrymme kan påverka de renderade utdata när du använder en CSS-regel, till exempel white-space: pre
. Om du vill inaktivera den här prestandaoptimeringen och bevara tomt utrymme utför du någon av följande åtgärder:
- Lägg till
@preservewhitespace true
-direktivet överst i Razor -filen (.razor
) för att tillämpa inställningarna på en specifik komponent. - Lägg till
@preservewhitespace true
-direktivet i en_Imports.razor
-fil för att tillämpa inställningarna på en underkatalog eller på hela projektet.
I de flesta fall krävs ingen åtgärd eftersom appar vanligtvis fortsätter att bete sig normalt (men snabbare). Om borttagning av blanksteg orsakar ett återgivningsproblem för en viss komponent använder du @preservewhitespace true
i komponenten för att inaktivera den här optimeringen.
Tomt utrymme behålls i en komponents källpålägg. Text med endast blanksteg återges i webbläsarens DOM även om det inte finns någon visuell effekt.
Överväg följande komponentmarkering:
<ul>
@foreach (var item in Items)
{
<li>
@item.Text
</li>
}
</ul>
I föregående exempel visas följande onödiga mellanslag:
- Utanför
@foreach
kodblocket. - Runt elementet
<li>
. - Omkring utgång
@item.Text
.
En lista med 100 punkter resulterar i över 400 områden av tomrum. Inget av det extra mellanrummet påverkar det renderade utdatafilen.
När statisk HTML återges för komponenter behålls inte blanksteg i en HTML-tagg. Du kan till exempel visa återgivna utdata från följande <img>
-tagg i en komponent Razor fil (.razor
):
<img alt="Example image" src="img.png" />
Tomt utrymme bevaras inte från föregående markering:
<img alt="Example image" src="img.png" />
Rotkomponent
En rotkomponent Razor (rotkomponenten) är den första komponenten som laddas in i någon komponenthierarki som skapats av appen.
I en app som skapats från Blazor Web App-projektmallen anges App
komponenten (App.razor
) som standardrotkomponent av den typparameter som deklarerats för anropet till MapRazorComponents<TRootComponent>
i Program
-filen på serversidan. I följande exempel visas användningen av komponenten App
som rotkomponent, som är standard för en app som skapats från Blazor-projektmallen:
app.MapRazorComponents<App>();
Notera
Det går inte att göra en rotkomponent interaktiv, till exempel komponenten App
.
I en app som skapats från Blazor Server-projektmallen anges App
komponenten (App.razor
) som standardrotkomponent i Pages/_Host.cshtml
med hjälp av komponenttaggen:
<component type="typeof(App)" render-mode="ServerPrerendered" />
I en app som skapats från Blazor WebAssembly-projektmallen anges App
komponenten (App.razor
) som standardrotkomponenten i Program
-filen:
builder.RootComponents.Add<App>("#app");
I föregående kod anger CSS-väljaren #app
att komponenten App
har angetts för <div>
i wwwroot/index.html
med en id
av app
:
<div id="app">...</app>
MVC- och Razor Pages-appar kan också använda komponenttagghjälpen för att registrera statiskt renderade Blazor WebAssembly rotkomponenter:
<component type="typeof(App)" render-mode="WebAssemblyPrerendered" />
Statiskt renderade komponenter kan bara läggas till i appen. De kan inte tas bort eller uppdateras efteråt.
Mer information finns i följande resurser:
- Tagghjälp för komponent i ASP.NET Core
- Integrera ASP.NET Core Razor-komponenter med MVC- eller Razor Pages-
IHttpContextAccessor
/HttpContext
IHttpContextAccessor bör vanligtvis undvikas med interaktiv återgivning eftersom en giltig HttpContext inte alltid är tillgänglig.
IHttpContextAccessor kan användas för komponenter som återges statiskt på servern. Vi rekommenderar dock att du undviker det om det är möjligt.
HttpContext kan användas som en kaskaderande parameter endast i statiskt-renderade rotkomponenter för allmänna uppgifter, såsom att inspektera och ändra huvuden eller andra egenskaper i komponenten App
(Components/App.razor
). Värdet är alltid null
för interaktiv återgivning.
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
För scenarier där HttpContext krävs i interaktiva komponenter rekommenderar vi att du överför data via ihållande komponenttillstånd från servern. Mer information finns i ASP.NET Core-serversidan och Blazor Web App ytterligare säkerhetsscenarier.
Använd inte IHttpContextAccessor/HttpContext direkt eller indirekt i de Razor komponenterna i Blazor appar på serversidan. Blazor appar körs utanför ASP.NET Core-pipelinekontexten. Det HttpContext garanteras inte vara tillgängligt inom IHttpContextAccessor, och HttpContext garanteras inte ha kontexten som startade Blazor-appen.
Den rekommenderade metoden för att skicka begärandetillståndet till den Blazor appen är genom rotkomponentparametrar under appens första återgivning. Alternativt kan appen kopiera data till en begränsad tjänst i rotkomponentens initieringslivscykelhändelse för användning i hela appen. Mer information finns i ASP.NET Core-serversidan och Blazor Web App ytterligare säkerhetsscenarier.
En kritisk aspekt av säkerheten på serversidan Blazor är att användaren som är ansluten till en viss krets kan uppdateras någon gång efter att Blazor-kretsen har upprättats, men IHttpContextAccessorinte uppdateras. Mer information om hur du hanterar den här situationen med anpassade tjänster finns i ASP.NET Core-serversidan och Blazor Web App ytterligare säkerhetsscenarier.
ASP.NET Core