Megosztás a következőn keresztül:


ASP.NET Core Razor összetevői

Jegyzet

Ez nem a cikk legújabb verziója. Az aktuális kiadást ennek a cikknek a .NET 9-es verziójában nézze meg .

Figyelmeztetés

A ASP.NET Core ezen verziója már nem támogatott. További információ: .NET és .NET Core támogatási szabályzat. Az aktuális kiadást a jelen cikk .NET 9-es verziójában.

Fontos

Ezek az információk egy olyan előzetes termékre vonatkoznak, amelyet a kereskedelmi forgalomba kerülés előtt jelentősen módosíthatnak. A Microsoft nem vállal kifejezett vagy hallgatólagos szavatosságot az itt megadott információkra vonatkozóan.

Az aktuális kiadásért tekintse meg a cikk .NET 9-es verzióját.

Ez a cikk bemutatja, hogyan hozhat létre és használhat Razor összetevőket Blazor alkalmazásokban, beleértve az Razor szintaxissal, az összetevők elnevezésével, a névtérekkel és az összetevőparaméterekkel kapcsolatos útmutatást.

Razor összetevők

Blazor alkalmazások Razor összetevők, informálisan Blazor összetevők vagy csak összetevők. Az összetevők a felhasználói felület (UI) egy önálló része feldolgozási logikával, amely lehetővé teszi a dinamikus viselkedést. Az összetevők beágyazhatók, újra felhasználhatók, megoszthatók a projektek között, és használhatók az MVC- és Razor Pages-alkalmazásokban.

Az összetevők a böngésző Dokumentumobjektum-modelljének (DOM) memóriában lévő reprezentációjába, az úgynevezett render fa, renderelődnek, amely a felhasználói felület rugalmas és hatékony frissítésére szolgál.

Bár a "Razor összetevők" elnevezést osztanak meg más ASP.NET Core tartalommegjelenítési technológiákkal, Razor összetevőket meg kell különböztetni az ASP.NET Core alábbi különböző funkcióitól:

Fontos

Blazor Web Apphasználatakor a Blazor dokumentációs példaösszetevők többsége interaktivitást igényel, és bemutatja a cikkekben foglalt fogalmakat. Ha egy cikk által biztosított példaösszetevőt tesztel, győződjön meg arról, hogy az alkalmazás globális interaktivitást alkalmaz, vagy az összetevő interaktív renderelési módot alkalmaz. Erről a témáról további információt ASP.NET Core Blazor renderelési módok, amely a cikk utáni tartalomjegyzék következő cikke.

Összetevőosztályok

Az összetevőket C# és HTML jelölőnyelv kombinációjával implementáljuk Razor.razor fájlkiterjesztéssel rendelkező komponensfájlokban.

ComponentBase Razor összetevőfájlok által leírt összetevők alaposztálya. ComponentBase az összetevők legalacsonyabb absztrakcióját valósítja meg, a IComponent felületet. ComponentBase az alapvető funkciók összetevőtulajdonságait és metódusait határozza meg, például a beépített összetevők életciklus-eseményeinek feldolgozásához.

ComponentBase dotnet/aspnetcore hivatkozási forrás: A hivatkozási forrás további megjegyzéseket is tartalmaz a beépített életciklus eseményekkel kapcsolatban. Ne feledje azonban, hogy az összetevők funkcióinak belső implementációi bármikor, előzetes értesítés nélkül változhatnak.

Jegyzet

A .NET referenciaforrásra mutató dokumentációs hivatkozások általában betöltik az adattár alapértelmezett ágát, amely a .NET következő kiadásának aktuális fejlesztését jelöli. Egy adott kiadás címkéjének kiválasztásához használja az Ágak vagy címkék váltása legördülő listát. További információ: A ASP.NET Core-forráskód (dotnet/AspNetCore.Docs #26205) verziócímkéjének kiválasztása.

A fejlesztők általában Razor összetevőfájlokból (.razor) hoznak létre Razor összetevőket, vagy ComponentBasealapulnak, de az összetevők IComponentimplementálásával is felépíthetők. A IComponent implementáló fejlesztő által készített összetevők alacsony szintű vezérlést végezhetnek a renderelés felett, azzal a költséggel, hogy manuálisan kell aktiválniuk a renderelést olyan eseményekkel és életciklus-módszerekkel, amelyeket a fejlesztőnek létre kell hoznia és fenntartania.

A Blazor dokumentációs példakód és mintaalkalmazások által elfogadott további konvenciók ASP.NET Alapvető Blazor alapjaitalálhatók.

Razor szintaxis

Az összetevők Razor szintaxisthasználnak. A két Razor funkciót az összetevők, a irányelvek és a irányelvattribútumokszéles körben használják. Ezek a fenntartott kulcsszavak, amelyek @ előtaggal vannak ellátva, a Razor jelölésben jelennek meg:

  • Irányelvek: Az összetevő jelölőnyelvének fordítását vagy működését módosítja. Az @page irányelv például egy útvonalsablonnal rendelkező routable összetevőt határoz meg, amely közvetlenül a felhasználó kérése alapján érhető el a böngészőben egy adott URL-címen.

    Konvenció szerint egy összetevő definíciójának (.razor fájl) tetején lévő összetevők irányelvei konzisztens sorrendbe kerülnek. Ismétlődő irányelvek esetén az irányelvek névtér vagy típus szerint betűrendbe vannak helyezve, kivéve @using irányelveket, amelyek speciális másodszintű rendezéssel rendelkeznek.

    A következő sorrendet alkalmazzák a Blazor mintaalkalmazások és dokumentáció esetében. A Blazor projektsablon által biztosított összetevők eltérhetnek a következő sorrendtől, és eltérő formátumot használhatnak. Például Blazor keretrendszer Identity összetevői üres sorokat tartalmaznak @using irányelvek és @inject irányelvek blokkjai között. Saját alkalmazásaiban szabadon használhat egyéni rendezési sémát és formátumot.

    Dokumentáció és mintaalkalmazás Razor irányelv sorrendje:

    • @page
    • @rendermode (.NET 8 vagy újabb verzió)
    • @using
      • System névterek (betűrend)
      • Microsoft névterek (betűrend)
      • Külső API-névterek (betűrendben)
      • Alkalmazásnévterek (betűrendben)
    • Egyéb irányelvek (betűrend)

    Az irányelvek között nem jelennek meg üres sorok. Az irányelvek és a Razor korrektúra első sora között egy üres sor jelenik meg.

    Példa:

    @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>
    
    ...
    
  • irányelv attribútumai: Az összetevőelemek fordítási módjának vagy működésének módosítása.

    Példa:

    <input @bind="episodeId" />
    

    A direktíva-attribútumértékeket a nem explicit Razor kifejezésekhez (@bind="@episodeId") az at szimbólummal (@) lehet illeszteni, de nem javasoljuk, és a dokumentumok nem alkalmazzák a megközelítést a példákban.

Az összetevőkben használt irányelveket és irányelvattribútumokat ebben a cikkben és a Blazor dokumentációs készlet egyéb cikkeiben ismertetjük. A Razor szintaxissal kapcsolatos általános információkért tekintse meg Razor ASP.NET Coreszintaxisának hivatkozását.

Összetevő neve, osztályneve és névtere

Az összetevő nevének nagybetűvel kell kezdődnie:

ProductDetail.razor

nem támogatott:productDetail.razor

A Blazor dokumentációban használt általános Blazor elnevezési konvenciók a következők:

  • A fájl elérési útjai és fájlnevei Pascal-esetet használnak† és a kód példák megjelenítése előtt jelennek meg. Ha van elérési út, az a mappa tipikus helyét jelzi. A Components/Pages/ProductDetail.razor például azt jelzi, hogy a ProductDetail összetevő fájlneve ProductDetail.razor, és az alkalmazás Components mappájának Pages mappájában található.
  • Az összekapcsolható összetevők összetevőfájl-elérési útjai megegyeznek a kebab-eset URL-címeivel‡ az összetevő útvonalsablonjában lévő szavak között megjelenő kötőjelekkel. Például a ProductDetail összetevőt /product-detail (@page "/product-detail") útvonalsablonnal kérik a böngészőben a relatív URL /product-detail-nál.

†A Pascal-névalak egy elnevezési konvenció, amelyben nincsenek szóközök és írásjelek, és minden szó első betűje nagy, beleértve az első szót is.
‡A Kebab-eset szóközök és írásjelek nélküli elnevezési konvenció, amely kisbetűket és kötőjeleket használ a szavak között.

A komponensek normál C#-osztályok, és a projekt bármely pontján elhelyezhetők. A weblapokat előállító összetevők általában a Components/Pages mappában találhatók. A nem oldalösszetevők gyakran a Components mappába vagy a projekthez hozzáadott egyéni mappába kerülnek.

Az összetevő névtere általában az alkalmazás gyökérnévteréből és az összetevő alkalmazáson belüli helyéből (mappájából) származik. Ha az alkalmazás gyökérnévtere BlazorSample, és a Counter összetevő a Components/Pages mappában található:

  • A Counter összetevő névtere BlazorSample.Components.Pages.
  • Az összetevő teljes típusneve az BlazorSample.Components.Pages.Counter.

Az összetevőket tartalmazó egyéni mappák esetében adjon hozzá egy @using direktívát a szülőösszetevőhöz vagy az alkalmazás _Imports.razor fájlhoz. Az alábbi példa a AdminComponents mappában lévő összetevőket teszi elérhetővé:

@using BlazorSample.AdminComponents

Jegyzet

@using irányelvei a _Imports.razor fájlban csak a Razor fájlokra (.razor) vonatkoznak, nem pedig a C# fájlokra (.cs).

Támogatottak az aliasos using utasítások. Az alábbi példában a GridRendering összetevő nyilvános WeatherForecast osztálya WeatherForecast ként érhető el az alkalmazás más részein található összetevőben:

@using WeatherForecast = Components.Pages.GridRendering.WeatherForecast

Az összetevők a teljes névvel is hivatkozhatók, ami nem igényel @using irányelvet. Az alábbi példa közvetlenül az alkalmazás AdminComponents/Pages mappájában található ProductDetail összetevőre hivatkozik:

<BlazorSample.AdminComponents.Pages.ProductDetail />

A Razor által létrehozott összetevő névtere a következő (prioritási sorrendben):

  • A Razor fájl jelölésében szerepel a @namespace utasítás (például @namespace BlazorSample.CustomNamespace).
  • A projekt RootNamespace a projektfájlban (például <RootNamespace>BlazorSample</RootNamespace>).
  • A projektnévtér és a projektgyökértől az összetevőig vezető út. A keretrendszer például a {PROJECT NAMESPACE}/Components/Pages/Home.razor-t a BlazorSample projekt névtere feloldja a BlazorSample.Components.Pages névtérre a Home összetevő esetében. {PROJECT NAMESPACE} a projektnévtér. Az összetevők c# névkötési szabályokat követnek. A példában szereplő Home összetevő esetében a hatókörben lévő összetevők az összes összetevőt képezik:
    • Ugyanabban a mappában Components/Pages.
    • A projekt gyökerében lévő összetevők, amelyek nem adnak meg explicit módon egy másik névteret.

Az alábbiak nem támogatottak:

  • A global:: minősítés.
  • Részlegesen kvalifikált nevek. Például nem adhat hozzá egy összetevőhöz @using BlazorSample.Components-t, majd nem hivatkozhat az alkalmazás Components/Layout mappájában lévő NavMenu összetevőre (Components/Layout/NavMenu.razor) <Layout.NavMenu></Layout.NavMenu>-al.

Az összetevő nevének nagybetűvel kell kezdődnie:

✔️ ProductDetail.razor

nem támogatott:productDetail.razor

A Blazor dokumentációban használt általános Blazor elnevezési konvenciók a következők:

  • A fájl elérési útjai és fájlnevei Pascal-esetet használnak† és a kód példák megjelenítése előtt jelennek meg. Ha van elérési út, az a mappa tipikus helyét jelzi. A Pages/ProductDetail.razor például azt jelzi, hogy a ProductDetail összetevő fájlneve ProductDetail.razor, és az alkalmazás Pages mappájában található.
  • Az összekapcsolható összetevők összetevőfájl-elérési útjai megegyeznek a kebab-eset URL-címeivel‡ az összetevő útvonalsablonjában lévő szavak között megjelenő kötőjelekkel. Például egy /product-detail (@page "/product-detail") útvonalsablont tartalmazó ProductDetail összetevőt kérnek a böngészőben a relatív URL-/product-detail.

†A Pascal-case egy elnevezési konvenció, amely nem használ szóközöket és írásjeleket, és az egyes szavak első betűi, beleértve az első szót is, nagybetűsek.
‡A Kebab-eset szóközök és írásjelek nélküli elnevezési konvenció, amely kisbetűket és kötőjeleket használ a szavak között.

Az összetevők C#-osztályok, és a projekt bármely pontján elhelyezhetők. A weblapokat előállító összetevők általában a Pages mappában találhatók. A nem oldalösszetevők gyakran a Shared mappába vagy a projekthez hozzáadott egyéni mappába kerülnek.

Az összetevő névtere általában az alkalmazás gyökérnévteréből és az összetevő alkalmazáson belüli helyéből (mappájából) származik. Ha az alkalmazás gyökérnévtere BlazorSample, és a Counter összetevő a Pages mappában található:

  • A Counter összetevő névtere BlazorSample.Pages.
  • Az összetevő teljes típusneve a BlazorSample.Pages.Counter.

Az összetevőket tartalmazó egyéni mappák esetében adjon hozzá egy @using direktívát a szülőösszetevőhöz vagy az alkalmazás _Imports.razor fájlhoz. Az alábbi példa a AdminComponents mappában lévő összetevőket teszi elérhetővé:

@using BlazorSample.AdminComponents

Jegyzet

@using irányelvei a _Imports.razor fájlban csak a Razor fájlokra (.razor), nem pedig a C# fájlokra (.cs) vonatkoznak.

Az aliasos using utasítások támogatottak. Az alábbi példában a GridRendering összetevő nyilvános WeatherForecast osztálya WeatherForecast ként érhető el az alkalmazás más részein található összetevőben:

@using WeatherForecast = Pages.GridRendering.WeatherForecast

Az összetevők a teljes névvel is hivatkozhatók, ami nem igényel @using irányelvet. Az alábbi példa közvetlenül az alkalmazás Components mappájában található ProductDetail összetevőre hivatkozik:

<BlazorSample.Components.ProductDetail />

A Razor által létrehozott összetevő névtere a következő (prioritási sorrendben):

  • A Razor fájl jelölésében a @namespace irányelv (például @namespace BlazorSample.CustomNamespace).
  • A projekt RootNamespace a projektfájlban (például a <RootNamespace>BlazorSample</RootNamespace>).
  • A projektnévtér és a projektgyökértől az összetevőig vezető út. Például a keretrendszer a {PROJECT NAMESPACE}/Pages/Index.razor-t a BlazorSample projektnévtérrel a BlazorSample.Pages névtérre oldja fel a Index összetevő esetében. A {PROJECT NAMESPACE} a projekt névtér. Az összetevők c# névkötési szabályokat követnek. A példában szereplő Index összetevő esetében a hatókörben lévő összetevők az összes összetevőt képezik:
    • Ugyanabban a mappában Pages.
    • A projekt gyökerében lévő összetevők, amelyek nem adnak meg explicit módon egy másik névteret.

Az alábbiak nem támogatottak:

  • A global:: minősítés.
  • Részben minősített nevek. Például nem adhat hozzá @using BlazorSample egy összetevőhöz, és nem hivatkozhat az alkalmazás Shared mappájában lévő NavMenu összetevőre (Shared/NavMenu.razor) a <Shared.NavMenu></Shared.NavMenu>-vel.

Részleges osztálytámogatás

Az összetevők C# részleges osztályként jönnek létre, és az alábbi módszerek egyikével jönnek létre:

  • Egyetlen fájl egy vagy több @code blokkban, HTML-korrektúrában és Razor korrektúrában definiált C#-kódot tartalmaz. Blazor projektsablonok ezzel az egyfájlos megközelítéssel határozzák meg az összetevőket.
  • A HTML- és Razor-jelölések egy Razor fájlba (.razor) kerülnek. A C#-kód egy részleges osztályként (.cs) definiált kód mögötti fájlba kerül.

Jegyzet

Az összetevő-specifikus stílusokat meghatározó összetevő-stíluslap egy külön fájl (.css). Blazor A CSS-elkülönítés később kerül ismertetésre a ASP.NET Core Blazor CSS-elkülönítési.

Az alábbi példa az alapértelmezett Counter összetevőt mutatja be, amely @code blokkot tartalmaz egy alkalmazásban, amely egy Blazor projektsablonból jön létre. A korrektúra és a C#-kód ugyanabban a fájlban található. Ez az összetevő-létrehozás leggyakoribb megközelítése.

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++;
    }
}

Az alábbi Counter összetevő szétválasztja a bemutató HTML-t és Razor jelölést a C# kódtól egy részleges osztályú kód mögötti fájl használatával. A jelölőnyelv és a C# kód szétválasztását egyes szervezetek és fejlesztők előnyben részesítik, hogy a komponenskódot a munkamódszerükhöz igazítsák. A szervezet felhasználói felületének szakértője például az összetevő C# logikáján dolgozó másik fejlesztőtől függetlenül dolgozhat a bemutató rétegen. Ez a módszer akkor is hasznos, ha automatikusan generált kóddal vagy forrásgenerátorokkal dolgozik. További információ: Részleges osztályok és módszerek (C# programozási útmutató).

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++;
        }
    }
}

A @using utasítások a _Imports.razor fájlban csak a Razor fájlokra (.razor) vonatkoznak, és nem a C# fájlokra (.cs). Szükség szerint adjon hozzá névtereket egy részleges osztályfájlhoz.

Az összetevők által használt tipikus névterek:

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;

A tipikus névterek közé tartozik az alkalmazás névtere és az alkalmazás Components mappájának megfelelő névtér is:

using BlazorSample;
using BlazorSample.Components;

További mappákat is tartalmazhat, például a Layout mappát:

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;

A tipikus névterek közé tartozik az alkalmazás névtere és az alkalmazás Shared mappájának megfelelő névtér is:

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;

A tipikus névterek közé tartozik az alkalmazás névtere és az alkalmazás Shared mappájának megfelelő névtér is:

using BlazorSample;
using BlazorSample.Shared;

Alaposztály megadása

A @inherits irányelv egy összetevő alaposztályának megadására szolgál. A részleges osztályokhasználatával ellentétben, amelyek csak a C# logikából osztják fel a korrektúrát, az alaposztály használatával örökölheti a C# kódot az alaposztály tulajdonságaival és metódusaival rendelkező összetevők egy csoportjában való használatra. Az alaposztályok használata csökkenti a kódredundanciát az alkalmazásokban, és akkor hasznos, ha alapkódot ad meg az osztálykódtárakból több alkalmazásnak. További információkért lásd: Öröklés C# és .NET.

Az alábbi példában a BlazorRocksBase1 alaposztály ComponentBaseszármazik.

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!";
}

Útválasztás

A Blazor útválasztása úgy érhető el, hogy egy útvonalsablont biztosít az alkalmazás minden akadálymentes összetevőjének egy @page irányelvvel. Ha egy @page irányelvvel rendelkező Razor-fájlt állít össze, a generált osztály kap egy RouteAttribute, amely megadja az útvonalsablont. Futásidőben az útválasztó keres egy RouteAttribute jelöléssel ellátott összetevőosztályokat, és megjeleníti azt az összetevőt, amelynek útvonalsablonja megfelel a kért URL-címnek.

Az alábbi HelloWorld összetevő /hello-worldútvonalsablont használ, és az összetevő renderelt weblapja a relatív URL-/hello-worldérhető el.

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>

Az előző összetevő betöltődik a böngésző /hello-world címre, függetlenül attól, hogy hozzáadja vagy sem az összetevőt az alkalmazás felhasználói felületének navigációjához. Ha szükséges, az összetevők hozzáadhatók a NavMenu összetevőhöz, így az összetevőre mutató hivatkozás megjelenik az alkalmazás felhasználói felületén alapuló navigációban.

Az előző HelloWorld összetevőhöz hozzáadhat egy NavLink összetevőt a NavMenu összetevőhöz. További információkért, beleértve a NavLink és NavMenu összetevők leírását, tekintse meg ASP.NET Core Blazor útválasztási és navigációs.

Jelölés

Az összetevők felhasználói felülete Razor szintaxishasználatával van definiálva, amely Razor korrektúrából, C#-ból és HTML-ből áll. Egy alkalmazás fordításakor a HTML-korrektúra és a C#-renderelési logika összetevőosztálysá alakul. A létrehozott osztály neve megegyezik a fájl nevével.

Az összetevőosztály tagjai egy vagy több @code blokkban vannak definiálva. @code blokkokban az összetevő állapota a C#-tal van megadva és feldolgozva:

  • Tulajdonság- és mező inicializálók.
  • A szülőösszetevők és az útvonalparaméterek által átadott argumentumok paraméterértékei.
  • A felhasználói eseménykezelés, az életciklus-események és az egyéni összetevőlogika módszerei.

Az összetevőtagok a @ szimbólummal kezdődő C#-kifejezések használatával jelenítik meg a logikát. Egy C#-mező például a mezőnévre @ előtaggal jelenik meg. A következő Markup összetevő kiértékeli és rendereli:

  • headingFontStyle a címsorelem CSS-tulajdonságértékének font-style.
  • headingText a címsorelem tartalmához.

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!";
}

Jegyzet

A Blazor dokumentációban olyan példákat talál, amelyek a private hozzáférés-módosító esetén a magántagokra vonatkoznak. A privát tagok hatóköre egy összetevő osztályára terjed ki. A C# azonban akkor feltételezi a private hozzáférés-módosítóját, ha nincs hozzáférés-módosító, ezért a tagok "private" explicit megjelölése a saját kódjában nem kötelező. A hozzáférés-módosítókkal kapcsolatos további információkért lásd Access Modifiers (C# programozási útmutató).

A Blazor keretrendszer egy összetevőt belsőleg dolgoz fel renderelési fa, amely az összetevő DOM-jának és kaszkádolt stíluslapobjektum-modelljének (CSSOM)kombinációja. Az összetevő első renderelése után az összetevő renderelési fája újragenerálódik az eseményekre válaszul. Blazor összehasonlítja az új renderfát az előző renderelt fával, és a böngésző DOM-ján bármilyen módosítást alkalmaz megjelenítésre. További információért lásd: ASP.NET Core Razor összetevők renderelése.

Razor C# vezérlőstruktúrák, irányelvek és irányelvattribútumok szintaxisa kisbetűs (például: @if, @code, @bind). A tulajdonságnevek nagybetűk (például @BodyLayoutComponentBase.Bodyesetén).

Az aszinkron metódusok (async) nem támogatják a void visszaadást.

A Blazor keretrendszer nem követi nyomon a void-et visszaadó aszinkron metódusokat (async). Ennek eredményeként a kivételek nem kerülnek elkapásra, ha void kerül visszaadásra. Mindig adjon vissza egy Task-t aszinkron metódusokból.

Beágyazott összetevők

Az összetevők más összetevőket is tartalmazhatnak, ha HTML-szintaxissal deklarálják őket. Az összetevők használatára vonatkozó korrektúra HTML-címkének tűnik, ahol a címke neve az összetevő típusa.

Vegye figyelembe a következő Heading összetevőt, amelyet más összetevők is használhatnak a címsorok megjelenítéséhez.

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";
}

A HeadingExample összetevő alábbi korrektúrái az előző Heading összetevőt azon a helyen jelenítik meg, ahol a <Heading /> címke megjelenik.

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 />

Ha egy összetevő olyan HTML-elemet tartalmaz, amelynek nagybetűs első betűje nem egyezik meg egy azonos névtérben lévő összetevő nevével, figyelmeztetés jelenik meg, amely azt jelzi, hogy az elemnek váratlan neve van. Az összetevő névteréhez @using irányelv hozzáadása elérhetővé teszi az összetevőt, amely feloldja a figyelmeztetést. További információért lásd a összetevő neve, osztályneve és névtér szakaszt.

Az ebben a szakaszban látható Heading összetevő-példa nem rendelkezik @page irányelvvel, így a Heading összetevő nem érhető el közvetlenül a felhasználó számára a böngészőben küldött közvetlen kéréssel. Az @page irányelvvel rendelkező összetevők azonban beágyazhatók egy másik összetevőbe. Ha a Heading összetevő közvetlenül elérhető lenne a Razor fájl tetején található @page "/heading" beillesztésével, akkor az összetevő megjelenne a /heading és /heading-exampleböngészőkérések esetén.

Összetevőparaméterek

Összetevőparaméterek továbbítják az adatokat az összetevőknek, és az összetevő osztályán a nyilvános C# tulajdonságok révén, a [Parameter] attribútummalvannak meghatározva.

Az alábbi ParameterChild összetevő összetevőparaméterei a következők:

  • Beépített referenciatípusok.

  • Felhasználó által definiált referenciatípus (PanelBody) a Bootstrap-kártya törzsének átadásához Body.

    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; }
}

Figyelmeztetés

Az összetevőparaméterek kezdeti értékeinek megadása támogatott, de ne hozzon létre olyan összetevőt, amely az összetevő első renderelése után a saját paramétereire ír. További információért lásd: A paraméterek felülírásának elkerülése az ASP.NET Core-ban Blazor.

A ParameterChild összetevő összetevőparamétereit a HTML-címke azon argumentumai állíthatják be, amelyek a ParameterChild összetevő egy példányát jelenítik meg. A következő szülőösszetevő két ParameterChild összetevőt jelenít meg:

  • Az első ParameterChild összetevő paraméterargumentumok megadása nélkül jelenik meg.
  • A második ParameterChild összetevő a szülőösszetevőtől fogadja a Title és a Body értékeit, amely egy explicit C#-kifejezést használ a PanelBodytulajdonságainak beállításához.

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" })" />

Az alábbi renderelt HTML-jelölés a szülőösszetevőből ParameterChild összetevő alapértelmezett értékeit jeleníti meg, ha a szülőösszetevő nem ad meg összetevő paraméterértékeket. Amikor a szülőösszetevő összetevőparaméter-értékeket ad meg, a ParameterChild összetevő alapértelmezett értékeit cserélik le.

Jegyzet

Az egyértelműség kedvéért a renderelt CSS-stílusosztályok többsége és néhány elem nem jelenik meg az alábbi renderelt HTML jelölésben. Az alábbi példában bemutatott fő koncepció az, hogy a szülőösszetevő az összetevő paramétereit használva rendelt értékeket a gyermek összetevőhöz.

<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>

Rendeljen hozzá egy C#-mezőt, tulajdonságot vagy metódus eredményét egy összetevőparaméterhez HTML-attribútumértékként. Az attribútum értéke általában bármely olyan C#-kifejezés lehet, amely megfelel a paraméter típusának. Az attribútum értéke igény szerint egy Razor fenntartott @ szimbólummal is vezethet, de nem kötelező.

Ha az összetevő paramétere sztring típusú, akkor az attribútum értéke inkább C# sztringkonstansként lesz kezelve. Ha ehelyett egy C#-kifejezést szeretne megadni, használja a @ előtagot.

Az alábbi szülőösszetevő az előző ParameterChild összetevő négy példányát jeleníti meg, és a Title paraméterértékeket a következőre állítja:

Az ötödik ParameterChild összetevőpéldány is beállítja a Count paramétert. Figyelje meg, hogy egy stringtípusú paraméterhez @ előtag szükséges annak biztosításához, hogy a kifejezés ne sztringkonstansként legyen kezelve. A Count azonban egy null értékű egész szám (System.Int32), így Count@ előtag nélkül is megkaphatja a count értékét. Létrehozhat egy alternatív kódkonvenciót, amely megköveteli, hogy a szervezet fejlesztői mindig a @előtagot használják. Akárhogy is, csupán azt javasoljuk, hogy konzisztens megközelítést alkalmazzon az összetevőparaméterek Razor korrektúra során történő átadására.

A paraméterattribútum-értékekre vonatkozó idézőjelek a legtöbb esetben nem kötelezőek a HTML5-specifikáció szerint. A Value=this például Value="this"helyett támogatott. Javasoljuk azonban, hogy idézőjeleket használjon, mert így könnyebb megjegyezni őket, és széles körben használatosak a webalapú technológiákban.

A dokumentációban példakódok:

  • Mindig használjon idézőjeleket. Példa: Value="this".
  • Ne használja a @ előtagot nem-literekkel, hacsak nem muszáj. Példa: Count="count", ahol a count szám típusú változó. Count="@count" érvényes stilisztikai megközelítés, de a dokumentáció és a példák nem követik a konvenciót.
  • Mindig kerülje a @ literálokat a Razor kifejezéseken kívül. Példa: IsFixed="true". Ide tartoznak a kulcsszavak (például this) és a null, de tetszés szerint használhatja őket. A IsFixed="@true" például nem gyakori, de támogatott.

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";
    }
}

Jegyzet

Ha C#-tagot rendel egy összetevőparaméterhez, akkor ne használja előtagként a paraméter HTML-attribútumához a @-t.

Helyes (Title egy sztringparaméter, Count szám típusú paraméter):

<ParameterChild Title="@title" Count="count" />
<ParameterChild Title="@title" Count="@count" />

Helytelen:

<ParameterChild @Title="@title" @Count="count" />
<ParameterChild @Title="@title" @Count="@count" />

A Razor lapoktól (.cshtml) eltérően a Blazor nem végezhet aszinkron munkát egy Razor-kifejezésben egy összetevő renderelése közben. Ennek az az oka, hogy a Blazor interaktív felhasználói felületek megjelenítésére tervezték. Az interaktív felhasználói felületen a képernyőnek mindig meg kell jelennie valaminek, így nincs értelme letiltani a renderelési folyamatot. Ehelyett az aszinkron munka az aszinkron életciklus-eseményeksorán történik. Az egyes aszinkron életciklus-események után az összetevő ismét renderelhet. Az alábbi Razor szintaxis nem támogatott:

<ParameterChild Title="await ..." />
<ParameterChild Title="@await ..." />

Az előző példában szereplő kód fordítóhiba az alkalmazás létrehozásakor:

A "await" operátor csak aszinkron metóduson belül használható. Érdemes lehet megjelölni ezt a metódust az "async" módosítóval, és a visszatérési típust "Tevékenység" értékre módosítani.

Ha az előző példában szereplő Title paraméter értékét aszinkron módon szeretné beolvasni, az összetevő használhatja a OnInitializedAsync életciklus-eseményt, ahogy az alábbi példa is mutatja:

<ParameterChild Title="@title" />

@code {
    private string? title;
    
    protected override async Task OnInitializedAsync()
    {
        title = await ...;
    }
}

További információ: ASP.NET Core Razor-összetevők életciklusa.

Az explicit Razor kifejezés használata a paraméterekhez való hozzárendelés kifejezési eredményével való összefűzésére nem támogatott. Az alábbi példa a "Set by " szöveget szeretné összefűzni egy objektum tulajdonságértékével. Bár ez a szintaxis egy Razor lapon (.cshtml) támogatott, nem érvényes a gyermek Title paraméteréhez való hozzárendeléshez egy összetevőben. Az alábbi Razor szintaxist nem támogatja:

<ParameterChild Title="Set by @(panelData.Title)" />

Az előző példában szereplő kód fordítóhiba az alkalmazás létrehozásakor:

Az összetevők attribútumai nem támogatják az összetett tartalmakat (vegyes C# és korrektúra).

A komponált értékek hozzárendelésének támogatásához használjon metódust, mezőt vagy tulajdonságot. Az alábbi példa a "Set by " és egy objektum tulajdonságértékének összefűződését hajtja végre a C# metódusban 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";
    }
}

További információ: Razor ASP.NET Coreszintaxisának referenciája.

Figyelmeztetés

Az összetevőparaméterek kezdeti értékeinek megadása támogatott, de ne hozzon létre olyan összetevőt, amely az összetevő első renderelése után a saját paramétereire ír. További információért lásd: Az ASP.NET Core paraméterek felülírásának elkerülése Blazor.

Az összetevőparamétereket automatikus tulajdonságokkell deklarálni, ami azt jelenti, hogy nem tartalmazhatnak egyéni logikát a get vagy set hozzáférőikben. Az alábbi StartData tulajdonság például egy automatikus tulajdonság:

[Parameter]
public DateTime StartData { get; set; }

Ne helyezzen egyéni logikát a get vagy set tartozékba, mert az összetevőparaméterek kizárólag csatornaként szolgálnak a szülőösszetevők számára az információk gyermekösszetevőbe való áramlásához. Ha egy gyermekösszetevő-tulajdonság set hozzáférője olyan logikát tartalmaz, amely a szülőösszetevő újrarajzolását okozza, végtelen renderelési ciklus jön létre.

Fogadott paraméterérték átalakítása:

  • Hagyja a paramétertulajdonságot automatikus tulajdonságként a megadott nyers adatok megjelenítéséhez.
  • Hozzon létre egy másik tulajdonságot vagy metódust az átalakított adatok paramétertulajdonság alapján történő megadásához.

Felülbírálja a OnParametersSetAsync, hogy minden új adat érkeztetéskor átalakítsa a kapott paramétert.

A kezdeti érték összetevőparaméterbe írása támogatott, mert a kezdeti érték-hozzárendelések nem zavarják a Blazorautomatikus összetevő-renderelését. Az aktuális helyi DateTime hozzárendelése DateTime.Now-hez StartData-re érvényes szintaxis egy komponensben.

[Parameter]
public DateTime StartData { get; set; } = DateTime.Now;

A DateTime.Nowkezdeti hozzárendelése után ne hozzárendelni egy értéket StartData a fejlesztői kódban. További információért lásd: A paraméterek felülírásának elkerülése ASP.NET Core-ban Blazor.

A szükséges összetevőparaméter megadásához alkalmazza a [EditorRequired] attribútumot. Ha nincs megadva paraméterérték, a szerkesztők vagy a buildelési eszközök figyelmeztetéseket jeleníthetnek meg a felhasználó számára. Ez az attribútum csak a [Parameter] attribútummalmegjelölt tulajdonságokra érvényes. A EditorRequiredAttribute a tervezéskor és az alkalmazás létrehozásakor lesz érvényesítve. Az attribútum futásidőben nincs kényszerítve, és nem garantálja a nemnull paraméter értékét.

[Parameter]
[EditorRequired]
public string? Title { get; set; }

Az egysoros attribútumlisták is támogatottak:

[Parameter, EditorRequired]
public string? Title { get; set; }

Ne használja a required módosítót vagy a init kiegészítőt az összetevőparaméterek tulajdonságain. Az összetevőket általában reflexióhasználatával példányosítjuk és hozzárendeljük a paraméterértékeket, ami megkerüli a init és required által kialakított garanciákat. Ehelyett használja a [EditorRequired] attribútumot a szükséges összetevőparaméter megadásához.

Ne használja a init tartozék az összetevő paramétertulajdonságaira, mert az összetevő paraméterértékeinek ParameterView.SetParameterProperties beállításához tükrözésikell használnia, amely megfelel a csak init-only beállítási korlátozásnak. A szükséges összetevőparaméter megadásához használja a [EditorRequired] attribútumot.

Ne használja a init tartozék az összetevő paramétertulajdonságaira, mert az összetevő paraméterértékeinek ParameterView.SetParameterProperties beállításához tükrözésikell használnia, amely megfelel a csak init-only beállítási korlátozásnak.

A Tuples (API dokumentáció) támogatott az összetevőparaméterek és RenderFragment típusok számára. Az alábbi példa összetevő paraméterei három értéket adnak át a(z) Tuple-nak.

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);
}

Névvel ellátott tömbök támogatottak, ahogyan az alábbi példában látható:

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);
}

Idézet ©2005 Universal Pictures: Serenity (Nathan Fillion)

A Tuples (API dokumentáció) támogatott az összetevőparaméterek és a RenderFragment típusok esetében. Az alábbi példa egy összetevő paraméterére, amely három értéket továbbít egy Tuple-ba:

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);
}

Nevesített csuplok támogatottak, ahogyan az alábbi példában látható:

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);
}

Idézet ©2005 Universal Pictures: Serenity (Nathan Fillion)

A Tuples (API dokumentáció) az összetevőparaméterek és a RenderFragment típusok esetében támogatottak. Az alábbi összetevőparaméter-példa három értéket továbbít Tuple-ban:

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);
}

Nevesített tuple-ök támogatottak, ahogyan az alábbi példában látható:

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);
}

Idézet ©2005 Universal Pictures: Serenity (Nathan Fillion)

Útvonalparaméterek

Az összetevők megadhatnak útvonalparamétereket a @page irányelv útvonalsablonjában. A Blazor útválasztó útvonalparamétereket használ a megfelelő összetevőparaméterek feltöltéséhez.

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; }
}

További információkért tekintse meg az Útvonalparaméterek részt az ASP.NET Core Blazor útvonalvezérlés és navigációrészében. Az opcionális útvonalparaméterek is támogatottak, és ugyanabban a szakaszban szerepelnek. A több mappahatáron átnyúló útvonalakat rögzítő összes útvonalparaméterről ({*pageRoute}) az ASP.NET Coreútválasztási és navigációs Blazor rendszerében található Catch-all útvonalparaméterek című szakaszban olvashat.

További információ: Útválasztási paraméterekASP.NET Core Blazor útválasztási és navigációsszakasza. A választható útvonalparaméterek nem támogatottak, ezért két @page direktívára van szükség (további információt a Útvonalparaméterek szakaszban talál). A több mappahatáron áthaladó útvonalakat rögzítő összes útvonalparaméterről ({*pageRoute}) a ASP.NET Core Blazor útválasztási és navigációs Catch-all útvonalparaméterek című szakaszában olvashat.

Figyelmeztetés

Az alapértelmezés szerint engedélyezett tömörítéssel ne hozzon létre biztonságos (hitelesített/engedélyezett) interaktív kiszolgálóoldali összetevőket, amelyek nem megbízható forrásokból renderelik az adatokat. A nem megbízható források közé tartoznak az útvonalparaméterek, a lekérdezési sztringek, az JS interopból származó adatok, valamint a külső felhasználók által szabályozható egyéb adatforrások (adatbázisok, külső szolgáltatások). További információ: ASP.NET Core BlazorSignalR útmutató és Veszélyforrások elhárítási útmutatója ASP.NET Core Blazor interaktív kiszolgálóoldali renderelési.

Gyermek tartalom megjelenítési töredékek

Az összetevők beállíthatják egy másik összetevő tartalmát. A hozzárendelési összetevő biztosítja a tartalmat a gyermekösszetevő nyitó és záró címkéi között.

Az alábbi példában a RenderFragmentChild összetevő egy ChildContent összetevőparaméterrel rendelkezik, amely a felhasználói felület egy szegmensét mint RenderFragmentjeleníti meg. Az összetevő Razor jelölésén belül a ChildContent pozíció az, ahol a tartalom a végleges HTML kimenetben lesz megjelenítve.

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; }
}

Fontos

A RenderFragment tartalmat fogadó tulajdonságot konvenció szerint ChildContent kell nevezni.

eseményvisszahívások RenderFragmentnem támogatottak.

Az alábbi komponens tartalmat biztosít a RenderFragmentChild megjelenítéséhez azáltal, hogy a tartalmat a gyermekkomponens nyitó és záró címkéi között helyezi el.

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>

A renderelési töredékek a gyermektartalmak Blazor alkalmazásokban való megjelenítésére szolgálnak, és az alábbi cikkek és cikkszakaszok példákkal ismertetik őket:

Jegyzet

Blazor keretrendszer beépített Razor összetevői ugyanazt a ChildContent összetevőparaméter-konvencióval állítják be a tartalmat. Azokat az összetevőket, amelyek gyermektartalmat állítottak be, az API dokumentációjában ChildContent összetevőparaméter tulajdonságnévre (a "ChildContent" keresési kifejezéssel rendelkező API-t szűri).

Újrahasználható renderelési logika töredékeinek renderelése

A gyermekösszetevőket kizárólag a renderelési logika újrafelhasználásának módjaként lehet figyelembevenni. Bármely összetevő @code blokkjában definiáljon egy RenderFragment-et, és renderelje a töredéket tetszőleges helyről, ahányszor csak szükséges.

@RenderWelcomeInfo

<p>Render the welcome info a second time:</p>

@RenderWelcomeInfo

@code {
    private RenderFragment RenderWelcomeInfo =  @<p>Welcome to your new app!</p>;
}

További információért lásd: renderelési logika.

Ciklusváltozók összetevőparaméterekkel és gyermektartalommal

Az összetevők for cikluson belüli rendereléséhez helyi indexváltozóra van szükség, ha az összetevő paraméterei vagy RenderFragment gyermektartalmak használják a növekményes ciklus változóját.

Vegye figyelembe az alábbi RenderFragmentChild2 összetevőt, amelynek van egy komponens paramétere (Id) és egy renderelési töredéke a gyermektartalom megjelenítésére (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; }
}

Ha egy szülőösszetevőben jeleníti meg a RenderFragmentChild2 összetevőt, használjon helyi indexváltozót (ct a következő példában) a hurokváltozó helyett (c) az összetevő paraméterértékének hozzárendelésekor és a gyermekösszetevő tartalmának megadásakor:

@for (int c = 1; c < 4; c++)
{
    var ct = c;

    <RenderFragmentChild2 Id="@($"Child{ct}")">
        Count: @ct
    </RenderFragmentChild2>
}

Másik lehetőségként használjon foreach hurkot Enumerable.Range-sel a for hurok helyett:

@foreach (var c in Enumerable.Range(1, 3))
{
    <RenderFragmentChild2 Id="@($"Child{c}")">
        Count: @c
    </RenderFragmentChild2>
}

Összetevőkre mutató hivatkozások rögzítése

Az összetevők hivatkozásai lehetővé teszik egy összetevőpéldány hivatkozását parancsok kiállításához. Összetevőhivatkozás rögzítése:

  • Adjon hozzá egy @ref attribútumot a gyermekösszetevőhöz.
  • Definiáljon egy olyan mezőt, amelynek a típusa megegyezik a gyermekösszetevővel.

Az összetevő renderelése után a mező ki lesz töltve az összetevőpéldánysal. Ezután meghívhatja a .NET metódusokat az adott példányon.

Fontolja meg az alábbi ReferenceChild összetevőt, amely rögzít egy üzenetet, amikor a ChildMethod meghívásra kerül.

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);
    }
}

Az összetevőhivatkozás csak az összetevő renderelése után töltődik fel, és a kimenet tartalmazza a ReferenceChildelemét. Amíg az összetevő nem jelenik meg, nincs semmire hivatkozni. Ne kíséreljen meg közvetlenül eseménykezelőnek meghívni egy hivatkozott összetevőmetódust (például @onclick="childComponent!.ChildMethod(5)"), mert előfordulhat, hogy a referenciaváltozó nem lesz hozzárendelve a kattintási esemény hozzárendelésekor.

Ha módosítani szeretné az összetevő hivatkozásait a renderelés befejezése után, használja a OnAfterRender vagy OnAfterRenderAsync metódusokat.

Az alábbi példa az előző ReferenceChild összetevőt használja.

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);
    }
}

Míg az összetevőhivatkozások rögzítése hasonló szintaxist használ az elemhivatkozások rögzítésének , az összetevőhivatkozások rögzítése nem JavaScript-interop szolgáltatás. Az összetevőhivatkozások nem lesznek átadva a JavaScript-kódnak. Az összetevőhivatkozások csak .NET-kódban használatosak.

Fontos

Ne használjon összetevőhivatkozásokat a gyermekösszetevők állapotának megváltoztatására. Ehelyett használjon normál deklaratív összetevőparamétereket az adatok gyermekösszetevőknek való továbbításához. Az összetevőparaméterek használata esetén a gyermekösszetevők automatikusan a megfelelő időpontokban lesznek újrarendezésre. További információkért lásd a összetevő paraméterek szakaszt és a ASP.NET Core Blazor adatkötési cikket.

Attribútum alkalmazása

Az attribútumok az @attribute irányelvvel alkalmazhatók az összetevőkre. Az alábbi példa a [Authorize] attribútumot az összetevő osztályára alkalmazza:

@page "/"
@attribute [Authorize]

Feltételes HTML-elemattribútumok és DOM-tulajdonságok

Blazor a következő általános viselkedést alkalmazza:

  • HTML-attribútumok esetén Blazor a .NET-érték alapján feltételesen beállítja vagy eltávolítja az attribútumot. Ha a .NET-érték false vagy null, az attribútum nincs beállítva, vagy eltávolításra kerül, ha korábban be volt állítva.
  • DOM-tulajdonságok, például checked vagy valueesetén Blazor a DOM tulajdonságot a .NET érték alapján állítja be. Ha a .NET-érték false vagy null, a DOM tulajdonság alaphelyzetbe áll alapértelmezett értékre.

Azok a Razor szintaxisattribútumok, amelyek megfelelnek a HTML-attribútumoknak, és amelyek a DOM-tulajdonságoknak felelnek meg, továbbra sincsenek dokumentálva, mivel ez a keretrendszer implementációs részletei értesítés nélkül változhatnak.

Figyelmeztetés

Egyes HTML-attribútumoknak( például aria-pressed) "igaz" vagy "hamis" sztringértékekkel kell rendelkezniük. Mivel sztringértéket és nem logikai értéket igényelnek, .NET string-t kell használnia a bool helyett az értékük megadásához. Ezt a követelményt a böngésző DOM API-k állítják be.

Nyers HTML

A sztringek általában DOM-szövegcsomópontok használatával jelennek meg, ami azt jelenti, hogy az esetlegesen tartalmazott korrektúrákat figyelmen kívül hagyják, és konstans szövegként kezelik. A nyers HTML-kód megjelenítéséhez csomagolja a HTML-tartalmat egy MarkupString értékbe. Az érték HTML-ként vagy SVG-ként van elemezve, és be lesz szúrva a DOM-ba.

Figyelmeztetés

A nem megbízható forrásból létrehozott nyers HTML-kód renderelése biztonsági kockázatot jelent, és mindig kerülni kell.

Az alábbi példa bemutatja, hogy a MarkupString típus használatával statikus HTML-tartalomblokkot adhat hozzá egy összetevő renderelt kimenetéhez.

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 sablonok

A renderelési töredékek Razor sablonszintaxissal definiálhatóak, hogy meghatározzanak egy felhasználói felület-részletet. Razor sablonok a következő formátumot használják:

@<{HTML tag}>...</{HTML tag}>

Az alábbi példa bemutatja, hogyan adhatja meg RenderFragment és RenderFragment<TValue> értékeket, és hogyan jeleníthet meg sablonokat közvetlenül egy összetevőben. A renderelési töredékek argumentumként is átadhatók sablonalapú összetevőknek.

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; }
    }
}

Az előző kód renderelt kimenete:

<p>The time is 4/19/2021 8:54:46 AM.</p>
<p>Pet: Nutty Rex</p>

Statikus eszközök

Blazor a statikus eszközökhöz készült ASP.NET Core-alkalmazások konvencióját követi. A statikus objektumok a projekt web root (wwwroot) mappájában találhatók, vagy a wwwroot mappa alatti mappákban.

Egy statikus objektum webes gyökerére mutató hivatkozáshoz használjon egy alap relatív elérési utat (/). Az alábbi példában a logo.png fizikailag a {PROJECT ROOT}/wwwroot/images mappában található. {PROJECT ROOT} az alkalmazás projektgyökere.

<img alt="Company logo" src="/images/logo.png" />

Az összetevők nem támogatják a tilde-perjel jelölését (~/).

Az alkalmazás alapútvonalának beállításával kapcsolatos információkért lásd: ASP.NET Core kiszolgáló és üzembe helyezés Blazor.

A címkesegítők nem támogatottak az összetevőkben

A Tag Helpers nem támogatott az összetevőkben. Ha a címkesegítőhöz hasonló funkciókat szeretne biztosítani Blazor, hozzon létre egy olyan összetevőt, amely ugyanazokkal a funkciókkal rendelkezik, mint a Címkesegítő, és használja helyette az összetevőt.

Méretezhető vektorgrafika (SVG) képek

Mivel Blazor HTML-t jelenít meg, a böngésző által támogatott képek, köztük Skálázható vektorgrafika (SVG) képek (.svg), a <img> címkén keresztül támogatottak:

<img alt="Example image" src="image.svg" />

Hasonlóképpen, az SVG-képek támogatottak a stíluslapfájl CSS-szabályaiban (.css):

.element-class {
    background-image: url("image.svg");
}

Blazor támogatja a <foreignObject> elemet, hogy tetszőleges HTML-t jelenítsen meg egy SVG-ben. A korrektúra tetszőleges HTML-t, RenderFragmentvagy Razor összetevőt jelölhet.

Az alábbi példa a következőket mutatja be:

  • Egy string (@message) megjelenítése.
  • Kétirányú kötés egy <input> elemmel és egy value mezővel.
  • Egy Robot összetevő.
<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;
}

A whitespace renderelési viselkedése

Hacsak a @preservewhitespace irányelvet nem használják a trueértékkel, minden felesleges térköz el lesz távolítva, ha:

  • Bevezető vagy záró elemen belül.
  • Bevezető vagy követő egy RenderFragment/RenderFragment<TValue> paraméteren belül (például egy másik összetevőnek átadott gyermektartalom).
  • C#-kódblokkot előz meg vagy követ, például @if vagy @foreach.

A téreltávolítás hatással lehet a renderelt kimenetre a CSS-szabály, például a white-space: pre, használatakor. A teljesítményoptimalizálás letiltásához és a térköz megőrzéséhez hajtsa végre az alábbi műveletek egyikét:

  • Adja hozzá a @preservewhitespace true direktívát a Razor fájl tetején (.razor) egy adott összetevő előnyben részesítéséhez.
  • Adja hozzá a @preservewhitespace true direktívát egy _Imports.razor fájlba, hogy a beállításokat egy alkönyvtárra vagy a teljes projektre alkalmazza.

A legtöbb esetben nincs szükség műveletre, mivel az alkalmazások általában továbbra is normálisan (de gyorsabban) viselkednek. Ha a térköz leválasztása renderelési problémát okoz egy adott összetevő esetében, az összetevőben található @preservewhitespace true használatával tiltsa le ezt az optimalizálást.

A whitespace megmarad az összetevő forrásjelölésében. A csak szóközökből álló szöveg akkor is megjelenik a böngésző DOM-jában, ha nincs vizuális hatása.

Vegye figyelembe a következő összetevő jelölést:

<ul>
    @foreach (var item in Items)
    {
        <li>
            @item.Text
        </li>
    }
</ul>

Az előző példa az alábbi felesleges szóközöket jeleníti meg:

  • A @foreach kódblokkon kívül.
  • A <li> elem körül.
  • A @item.Text kimenet körül.

A 100 elemből álló lista több mint 400 üres területet eredményez. Az extra üres tér egyik sem befolyásolja vizuálisan a renderelt kimenetet.

Az összetevők statikus HTML-jének renderelésekor a címkéken belüli térköz nem marad meg. Megtekintheti például a következő <img> címke renderelt kimenetét egy összetevő Razor fájlban (.razor):

<img     alt="Example image"   src="img.png"     />

A whitespace nem marad meg az előző korrektúra alapján:

<img alt="Example image" src="img.png" />

Gyökérösszetevő

A gyökér-Razor összetevő (gyökérösszetevő) az alkalmazás által létrehozott összetevők hierarchiájának első eleme.

A Blazor Web App projektsablonból létrehozott alkalmazásban a App összetevőt (App.razor) a kiszolgálóoldali Program fájlban MapRazorComponents<TRootComponent> híváshoz deklarált típusparaméter adja meg alapértelmezett fő összetevőként. Az alábbi példa a App összetevő fő összetevőként való használatát mutatja be, amely a Blazor projektsablonból létrehozott alkalmazás alapértelmezett eleme:

app.MapRazorComponents<App>();

Jegyzet

A gyökérösszetevő interaktívvá tétele, például a App összetevő nem támogatott.

A Blazor Server projektsablonból létrehozott alkalmazásban a App összetevő (App.razor) van megadva alapértelmezett gyökérösszetevőként a Pages/_Host.cshtml-ban a összetevő címke segítőjehasználatával:

<component type="typeof(App)" render-mode="ServerPrerendered" />

A Blazor WebAssembly projektsablonból létrehozott alkalmazásban a App összetevő (App.razor) van megadva a Program fájl alapértelmezett gyökérösszetevőjeként:

builder.RootComponents.Add<App>("#app");

Az előző kódban a CSS-választó (#app) azt jelzi, hogy a App összetevő a wwwroot/index.html-on belül, id-ként van megadva a <div>-ben, appértékkel.

<div id="app">...</app>

Az MVC- és Razor Pages-alkalmazások a összetevőcímke-segéd-t is használhatják statikusan renderelt Blazor WebAssembly gyökérösszetevők regisztrálásához.

<component type="typeof(App)" render-mode="WebAssemblyPrerendered" />

Statikusan renderelt összetevők csak az alkalmazáshoz vehetők fel. Ezeket később nem lehet eltávolítani vagy frissíteni.

További információ:

IHttpContextAccessor/HttpContext

IHttpContextAccessor-t általában el kellene kerülni az interaktív megjelenítésnél, mert egy érvényes HttpContext nem mindig érhető el.

IHttpContextAccessor a kiszolgálón statikusan renderelt összetevőkhöz használható. Javasoljuk azonban, hogy ha lehetséges, kerülje el.

HttpContext kaszkádolt paraméterként csak statikusan renderelt főösszetevőkben általános feladatokhoz, például az élőfejek vagy a App összetevő egyéb tulajdonságainak (Components/App.razor) vizsgálatához és módosításához használható. Az érték mindig null interaktív rendereléshez.

[CascadingParameter]
public HttpContext? HttpContext { get; set; }

Olyan esetekben, amikor az interaktív összetevőkben szükség van a HttpContext-ra, javasoljuk, hogy az adatokat a kiszolgálóról érkező állandó összetevő állapotán keresztül áramoltassa. További információ: ASP.NET Core kiszolgálóoldali és Blazor Web App további biztonsági forgatókönyvek.

Ne használjon közvetlenül vagy közvetve IHttpContextAccessor/HttpContext a kiszolgálóoldali Blazor-alkalmazások Razor összetevőiben. Blazor alkalmazások a ASP.NET Core-folyamat környezetén kívül futnak. A HttpContext elérhetősége a IHttpContextAccessoresetében nem garantált, és nem garantált, hogy a HttpContext tartalmazza azt a környezetet, amely elindította a Blazor alkalmazást.

A kérésállapot Blazor alkalmazásnak való átadásának ajánlott módszere a gyökérösszetevő paraméterein keresztül történik az alkalmazás kezdeti renderelése során. Másik lehetőségként az alkalmazás átmásolhatja az adatokat egy hatókörrel rendelkező szolgáltatásba a gyökérösszetevő inicializálási életciklus-eseményében az alkalmazás egészére való használatra. További információ: ASP.NET Core kiszolgálóoldali és Blazor Web App további biztonsági forgatókönyvek.

A kiszolgálóoldali Blazor biztonság egyik kritikus eleme, hogy az adott kapcsolatcsoporthoz csatlakoztatott felhasználó a Blazor kapcsolatcsoport létrehozása után bizonyos időpontban frissülhet, de a IHttpContextAccessornem frissül. A helyzet egyéni szolgáltatásokkal való kezelésére vonatkozó további információkért lásd ASP.NET Core kiszolgálóoldali és Blazor Web App további biztonsági forgatókönyveket.