Komponen Razor ASP.NET Core
Catatan
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Peringatan
Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Penting
Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Artikel ini menjelaskan cara membuat dan menggunakan komponen Razor di aplikasi Blazor, termasuk panduan tentang sintaks Razor, penamaan komponen, namespace layanan, dan parameter komponen.
Komponen Razor
Blazor aplikasi dibangun menggunakan Razor komponen, secara informal dikenal sebagai Blazor komponen atau hanya komponen. Komponen adalah bagian mandiri dari antarmuka pengguna (UI) dengan logika pemrosesan untuk mengaktifkan perilaku dinamis. Komponen dapat ditumpuk, digunakan kembali, dibagikan di antara proyek, dan digunakan di aplikasi MVC dan Razor Pages.
Komponen dirender menjadi representasi dalam memori Model Objek Dokumen (DOM) browser yang disebut pohon render, yang digunakan untuk memperbarui UI dengan cara yang fleksibel dan efisien.
Meskipun "Razor komponen" berbagi beberapa penamaan dengan teknologi penyajian konten ASP.NET Core lainnya, Razor komponen harus dibedakan dari berbagai fitur berikut di ASP.NET Core:
- Razor tampilan, yang merupakan Razorhalaman markup berbasis untuk aplikasi MVC.
- Lihat komponen, yang untuk merender potongan konten daripada seluruh respons di Razor Halaman dan aplikasi MVC.
Penting
Saat menggunakan , sebagian Blazor besar komponen contoh dokumentasi memerlukan interaktivitas untuk berfungsi dan menunjukkan konsep yang dibahas oleh artikel.Blazor Web App Saat Anda menguji komponen contoh yang disediakan oleh artikel, pastikan aplikasi mengadopsi interaktivitas global atau komponen mengadopsi mode render interaktif. Informasi selengkapnya tentang subjek ini disediakan oleh mode render ASP.NET CoreBlazor, yang merupakan artikel berikutnya dalam daftar isi setelah artikel ini.
Kelas komponen
Komponen diimplementasikan menggunakan kombinasi markup C# dan HTML dalam file komponen Razor dengan ekstensi file .razor
.
ComponentBase adalah kelas dasar untuk komponen yang dijelaskan oleh Razor file komponen. ComponentBase mengimplementasikan abstraksi komponen terendah, IComponent antarmuka. ComponentBase menentukan properti komponen dan metode untuk fungsionalitas dasar, misalnya, untuk memproses serangkaian peristiwa siklus hidup komponen bawaan.
ComponentBase
di dotnet/aspnetcore
sumber referensi: Sumber referensi berisi komentar tambahan pada peristiwa siklus hidup bawaan. Namun, perlu diingat bahwa implementasi internal fitur komponen dapat berubah kapan saja tanpa pemberitahuan.
Catatan
Tautan dokumentasi ke sumber referensi .NET biasanya memuat cabang default repositori, yang mewakili pengembangan saat ini untuk rilis .NET berikutnya. Untuk memilih tag rilis tertentu, gunakan daftar dropdown Beralih cabang atau tag. Untuk informasi lebih lanjut, lihat Cara memilih tag versi kode sumber ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Pengembang biasanya membuat komponen dari Razor file komponen (.razor
) atau mendasarkan komponennya pada ComponentBase, tetapi komponen juga dapat dibangun dengan menerapkan IComponent.Razor Komponen yang dibangun pengembang yang diterapkan IComponent dapat mengambil kontrol tingkat rendah atas penyajian dengan biaya harus memicu penyajian secara manual dengan peristiwa dan metode siklus hidup yang harus dibuat dan dikelola pengembang.
Konvensi tambahan yang diadopsi oleh Blazor kode contoh dokumentasi dan aplikasi sampel ditemukan dalam dasar-dasar ASP.NET CoreBlazor.
Razor sintaks
Komponen menggunakan sintaks Razor. Dua fitur Razor banyak digunakan oleh komponen, arahan dan atribut arahan. Ini adalah kata kunci khusus yang diawali dengan @
, yang muncul di markup Razor:
Arahan: Mengubah cara markup komponen dikompilasi atau fungsi. Misalnya, direktif
@page
menentukan komponen yang dapat dirutekan dengan templat rute yang dapat dijangkau langsung oleh permintaan pengguna di browser pada URL tertentu.Menurut konvensi, arahan komponen di bagian atas definisi komponen (
.razor
file) ditempatkan dalam urutan yang konsisten. Untuk arahan berulang, arahan ditempatkan menurut abjad menurut namespace atau jenis, kecuali@using
direktif, yang memiliki urutan tingkat kedua khusus.Urutan berikut diadopsi oleh Blazor aplikasi sampel dan dokumentasi. Komponen yang Blazor disediakan oleh templat proyek mungkin berbeda dari urutan berikut dan menggunakan format yang berbeda. Misalnya, Blazor komponen kerangka kerja Identity mencakup baris kosong antara blok arahan
@using
dan blok arahan@inject
. Anda bebas menggunakan skema dan format pemesanan kustom di aplikasi Anda sendiri.Dokumentasi dan contoh urutan direktif aplikasi Razor :
@page
@rendermode
(.NET 8 atau yang lebih baru)@using
System
namespace (urutan alfabet)Microsoft
namespace (urutan alfabet)- Namespace API pihak ketiga (urutan alfabet)
- Namespace aplikasi (urutan alfabet)
- Direktif lain (urutan alfabet)
Tidak ada baris kosong yang muncul di antara arahan. Satu baris kosong muncul antara direktif dan baris Razor pertama markup.
Contoh:
@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> ...
Atribut direktif: Mengubah cara elemen komponen dikompilasi atau fungsi.
Contoh:
<input @bind="episodeId" />
Anda dapat mengawali nilai atribut direktif dengan simbol at (
@
) untuk ekspresi non-eksplisit Razor (@bind="@episodeId"
), tetapi kami tidak merekomendasikannya, dan dokumen tidak mengadopsi pendekatan dalam contoh.
Atribut arahan dan arahan yang digunakan dalam komponen dijelaskan lebih lanjut dalam artikel ini dan artikel lain dari rangkaian dokumentasi Blazor. Untuk informasi umum tentang sintaks Razor, lihat referensi sintaks Razor untuk ASP.NET Core.
Nama komponen, nama kelas, dan namespace
Nama komponen harus dimulai dengan karakter huruf besar:
Didukung: ProductDetail.razor
Tidak didukung: productDetail.razor
Konvensi penamaan Blazor umum yang digunakan di seluruh dokumentasi Blazor meliputi:
- Jalur file dan nama file menggunakan kasus Pascal† dan muncul sebelum menampilkan contoh kode. Jika ada jalur, jalur menunjukkan lokasi folder umum. Misalnya,
Components/Pages/ProductDetail.razor
menunjukkan bahwaProductDetail
komponen memiliki namaProductDetail.razor
file dan berada diPages
folderComponents
folder aplikasi. - Jalur file komponen untuk komponen yang dapat dirutekan cocok dengan URL mereka dalam kasus kebab‡ dengan tanda hubung yang muncul di antara kata-kata dalam templat rute komponen. Misalnya, komponen
ProductDetail
dengan template rute/product-detail
(@page "/product-detail"
) diminta di browser di URL relatif/product-detail
.
†Pascal case (camel case dengan huruf besar) adalah konvensi penamaan tanpa spasi dan tanda baca dan dengan huruf pertama dari setiap kata dikapitalisasi, termasuk kata pertama.
‡Kasus Kebab adalah konvensi penamaan tanpa spasi dan tanda baca yang menggunakan huruf kecil dan tanda hubung antar kata.
Komponen adalah kelas C# biasa dan dapat ditempatkan di mana saja dalam suatu proyek. Komponen yang menghasilkan halaman web biasanya berada di folder Components/Pages
. Komponen non-halaman sering ditempatkan di folder Components
atau folder kustom yang ditambahkan ke proyek.
Biasanya, namespace layanan komponen berasal dari namespace layanan akar aplikasi dan lokasi komponen (folder) di dalam aplikasi. Jika namespace layanan akar aplikasi adalah BlazorSample
dan komponen Counter
berada di folder Components/Pages
:
- Namespace layanan komponen
Counter
adalahBlazorSample.Components.Pages
. - Nama jenis komponen yang sepenuhnya memenuhi syarat adalah
BlazorSample.Components.Pages.Counter
.
Untuk folder kustom yang menyimpan komponen, tambahkan arahan @using
ke komponen induk atau ke file _Imports.razor
aplikasi. Contoh berikut membuat komponen dalam folder AdminComponents
tersedia:
@using BlazorSample.AdminComponents
Catatan
Arahan @using
dalam file _Imports.razor
hanya diterapkan pada file Razor (.razor
), bukan file C# (.cs
).
Pernyataan alias using
didukung. Dalam contoh berikut, kelas GridRendering
publik WeatherForecast
komponen tersedia seperti WeatherForecast
di komponen di tempat lain di aplikasi:
@using WeatherForecast = Components.Pages.GridRendering.WeatherForecast
Komponen juga dapat direferensikan menggunakan nama yang sepenuhnya memenuhi syarat, yang tidak memerlukan arahan @using
. Contoh berikut secara langsung merujuk komponen ProductDetail
di folder AdminComponents/Pages
aplikasi:
<BlazorSample.AdminComponents.Pages.ProductDetail />
Namespace layanan komponen yang dibuat dengan Razor didasarkan pada hal berikut (dalam urutan prioritas):
- Arahan
@namespace
di markup file Razor (misalnya,@namespace BlazorSample.CustomNamespace
). RootNamespace
proyek dalam file proyek (misalnya,<RootNamespace>BlazorSample</RootNamespace>
).- Namespace layanan proyek dan jalur dari akar proyek ke komponen. Misalnya, kerangka kerja diselesaikan
{PROJECT NAMESPACE}/Components/Pages/Home.razor
dengan namespaceBlazorSample
proyek ke namespaceBlazorSample.Components.Pages
layanan untukHome
komponen.{PROJECT NAMESPACE}
adalah namespace proyek. Komponen mengikuti aturan pengikatan nama C#.Home
Untuk komponen dalam contoh ini, komponen dalam cakupan adalah semua komponen:- Dalam folder yang sama,
Components/Pages
. - Komponen di akar proyek yang tidak secara eksplisit menentukan namespace layanan yang berbeda.
- Dalam folder yang sama,
Berikut ini tidak didukung:
- Kualifikasi
global::
. - Nama yang memenuhi sebagian syarat. Misalnya, Anda tidak dapat menambahkan
@using BlazorSample.Components
ke komponen lalu merujuk komponenNavMenu
di folderComponents/Layout
aplikasi (Components/Layout/NavMenu.razor
) dengan<Layout.NavMenu></Layout.NavMenu>
.
Nama komponen harus dimulai dengan karakter huruf besar:
Didukung: ProductDetail.razor
Tidak didukung: productDetail.razor
Konvensi penamaan Blazor umum yang digunakan di seluruh dokumentasi Blazor meliputi:
- Jalur file dan nama file menggunakan kasus Pascal† dan muncul sebelum menampilkan contoh kode. Jika ada jalur, jalur menunjukkan lokasi folder umum. Misalnya,
Pages/ProductDetail.razor
menunjukkan bahwa komponenProductDetail
memiliki nama fileProductDetail.razor
dan berada di folderPages
aplikasi. - Jalur file komponen untuk komponen yang dapat dirutekan cocok dengan URL mereka dalam kasus kebab‡ dengan tanda hubung yang muncul di antara kata-kata dalam templat rute komponen. Misalnya, komponen
ProductDetail
dengan template rute/product-detail
(@page "/product-detail"
) diminta di browser di URL relatif/product-detail
.
†Pascal case (camel case dengan huruf besar) adalah konvensi penamaan tanpa spasi dan tanda baca dan dengan huruf pertama dari setiap kata dikapitalisasi, termasuk kata pertama.
‡Kasus Kebab adalah konvensi penamaan tanpa spasi dan tanda baca yang menggunakan huruf kecil dan tanda hubung antar kata.
Komponen adalah kelas C# biasa dan dapat ditempatkan di mana saja dalam suatu proyek. Komponen yang menghasilkan halaman web biasanya berada di folder Pages
. Komponen non-halaman sering ditempatkan di folder Shared
atau folder kustom yang ditambahkan ke proyek.
Biasanya, namespace layanan komponen berasal dari namespace layanan akar aplikasi dan lokasi komponen (folder) di dalam aplikasi. Jika namespace layanan akar aplikasi adalah BlazorSample
dan komponen Counter
berada di folder Pages
:
- Namespace layanan komponen
Counter
adalahBlazorSample.Pages
. - Nama jenis komponen yang sepenuhnya memenuhi syarat adalah
BlazorSample.Pages.Counter
.
Untuk folder kustom yang menyimpan komponen, tambahkan arahan @using
ke komponen induk atau ke file _Imports.razor
aplikasi. Contoh berikut membuat komponen dalam folder AdminComponents
tersedia:
@using BlazorSample.AdminComponents
Catatan
Arahan @using
dalam file _Imports.razor
hanya diterapkan pada file Razor (.razor
), bukan file C# (.cs
).
Pernyataan alias using
didukung. Dalam contoh berikut, kelas GridRendering
publik WeatherForecast
komponen tersedia seperti WeatherForecast
di komponen di tempat lain di aplikasi:
@using WeatherForecast = Pages.GridRendering.WeatherForecast
Komponen juga dapat direferensikan menggunakan nama yang sepenuhnya memenuhi syarat, yang tidak memerlukan arahan @using
. Contoh berikut secara langsung merujuk komponen ProductDetail
di folder Components
aplikasi:
<BlazorSample.Components.ProductDetail />
Namespace layanan komponen yang dibuat dengan Razor didasarkan pada hal berikut (dalam urutan prioritas):
- Arahan
@namespace
di markup file Razor (misalnya,@namespace BlazorSample.CustomNamespace
). RootNamespace
proyek dalam file proyek (misalnya,<RootNamespace>BlazorSample</RootNamespace>
).- Namespace layanan proyek dan jalur dari akar proyek ke komponen. Misalnya, kerangka kerja diselesaikan
{PROJECT NAMESPACE}/Pages/Index.razor
dengan namespaceBlazorSample
proyek ke namespaceBlazorSample.Pages
layanan untukIndex
komponen.{PROJECT NAMESPACE}
adalah namespace proyek. Komponen mengikuti aturan pengikatan nama C#.Index
Untuk komponen dalam contoh ini, komponen dalam cakupan adalah semua komponen:- Dalam folder yang sama,
Pages
. - Komponen di akar proyek yang tidak secara eksplisit menentukan namespace layanan yang berbeda.
- Dalam folder yang sama,
Berikut ini tidak didukung:
- Kualifikasi
global::
. - Nama yang memenuhi sebagian syarat. Misalnya, Anda tidak dapat menambahkan
@using BlazorSample
ke komponen lalu merujuk komponenNavMenu
di folderShared
aplikasi (Shared/NavMenu.razor
) dengan<Shared.NavMenu></Shared.NavMenu>
.
Dukungan kelas parsial
Komponen dibuat sebagai kelas parsial C# dan dibuat menggunakan salah satu pendekatan berikut:
- Satu file berisi kode C# yang ditentukan dalam satu atau beberapa blok
@code
, markup HTML, dan markup Razor. Template proyek Blazor menentukan komponennya menggunakan pendekatan file tunggal ini. - HTML dan markup Razor ditempatkan dalam file Razor (
.razor
). Kode C# ditempatkan dalam file di belakang kode yang didefinisikan sebagai kelas parsial (.cs
).
Catatan
Lembar gaya komponen yang mendefinisikan gaya khusus komponen adalah file terpisah (.css
). Isolasi CSS Blazor dijelaskan nanti di isolasi CSS Blazor ASP.NET Core.
Contoh berikut menunjukkan komponen Counter
default dengan blok @code
dalam aplikasi yang dihasilkan dari template proyek Blazor. Markup dan kode C# berada dalam file yang sama. Ini adalah pendekatan yang paling umum digunakan dalam penulisan komponen.
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++;
}
}
Komponen berikut Counter
membagi HTML presentasi dan Razor markup dari kode C# menggunakan file code-behind dengan kelas parsial. Memisahkan markup dari kode C# disukai oleh beberapa organisasi dan pengembang untuk mengatur kode komponen mereka agar sesuai dengan cara kerja mereka. Misalnya, pakar UI organisasi dapat mengerjakan lapisan presentasi secara independen dari pengembang lain yang mengerjakan logika C# komponen. Pendekatan ini juga berguna saat bekerja dengan kode yang dihasilkan secara otomatis atau generator sumber. Untuk informasi selengkapnya, lihat Kelas dan Metode Parsial (Panduan Pemrograman C#).
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++;
}
}
}
Arahan @using
dalam file _Imports.razor
hanya diterapkan pada file Razor (.razor
), bukan file C# (.cs
). Tambahkan namespace layanan ke file kelas parsial sesuai kebutuhan.
Namespace layanan umum yang digunakan oleh komponen:
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;
Namespace layanan umum juga mencakup namespace layanan aplikasi dan namespace layanan yang sesuai dengan folder Components
aplikasi:
using BlazorSample;
using BlazorSample.Components;
Folder tambahan juga dapat disertakan, seperti Layout
folder:
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;
Namespace layanan umum juga mencakup namespace layanan aplikasi dan namespace layanan yang sesuai dengan folder Shared
aplikasi:
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;
Namespace layanan umum juga mencakup namespace layanan aplikasi dan namespace layanan yang sesuai dengan folder Shared
aplikasi:
using BlazorSample;
using BlazorSample.Shared;
Menentukan kelas dasar
Arahan @inherits
digunakan untuk menentukan kelas dasar untuk suatu komponen. Tidak seperti menggunakan kelas parsial, yang hanya membagi markup dari logika C#, menggunakan kelas dasar memungkinkan Anda untuk mewarisi kode C# untuk digunakan di seluruh grup komponen yang berbagi properti dan metode kelas dasar. Menggunakan kelas dasar mengurangi redundansi kode di aplikasi dan berguna saat menyediakan kode dasar dari pustaka kelas ke beberapa aplikasi. Untuk informasi selengkapnya, lihat Warisan di C# dan .NET.
Dalam contoh berikut, BlazorRocksBase1
kelas dasar berasal dari 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!";
}
Perutean
Perutean di Blazor dicapai dengan menyediakan template rute ke setiap komponen yang dapat diakses di aplikasi dengan arahan @page
. Saat file Razor dengan arahan @page
dikompilasi, kelas yang dihasilkan diberi RouteAttribute yang menentukan template rute. Pada runtime bahasa umum, router mencari kelas komponen dengan RouteAttribute dan merender komponen mana pun yang memiliki template rute yang cocok dengan URL yang diminta.
Komponen berikut HelloWorld
menggunakan templat /hello-world
rute , dan halaman web yang dirender untuk komponen tercapai di URL /hello-world
relatif .
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>
Komponen sebelumnya dimuat di browser pada /hello-world
terlepas dari apakah Anda menambahkan komponen ke navigasi antarmuka pengguna aplikasi atau tidak. Secara opsional, komponen dapat ditambahkan ke komponen NavMenu
sehingga tautan ke komponen muncul di navigasi berbasis UI aplikasi.
Untuk komponen sebelumnya HelloWorld
, Anda dapat menambahkan NavLink
komponen ke NavMenu
komponen. Untuk informasi lebih lanjut, termasuk deskripsi komponen NavLink
dan NavMenu
, lihat perutean dan navigasi Blazor ASP.NET Core.
Markup
Antarmuka pengguna komponen ditentukan menggunakan sintaks Razor, yang terdiri dari markup Razor, C#, dan HTML. Saat aplikasi dikompilasi, markup HTML dan logika perenderan C# diubah menjadi kelas komponen. Nama kelas yang dihasilkan cocok dengan nama file.
Anggota kelas komponen didefinisikan dalam satu atau lebih blok @code
. Di blok @code
, status komponen ditentukan dan diproses dengan C#:
- Penginisialisasi properti dan bidang.
- Nilai parameter dari argumen yang diteruskan oleh komponen induk dan parameter rute.
- Metode untuk penanganan aktivitas pengguna, peristiwa siklus hidup, dan logika komponen kustom.
Anggota komponen digunakan dalam merender logika menggunakan ekspresi C# yang dimulai dengan simbol @
. Misalnya, bidang C# dirender dengan awalan @
pada nama bidang. Komponen Markup
berikut mengevaluasi dan merender:
headingFontStyle
untuk nilai properti CSSfont-style
dari elemen judul.headingText
untuk konten elemen judul.
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!";
}
Catatan
Contoh di seluruh dokumentasi Blazor menentukan pengubah akses private
untuk anggota privat. Anggota privat dicakupkan ke kelas komponen. Namun, C# mengasumsikan pengubah akses private
ketika tidak ada pengubah akses, jadi secara eksplisit menandai anggota sebagai "private
" dalam kode Anda sendiri sifatnya opsional. Untuk informasi lebih lanjut tentang pengubah akses, lihat Pengubah Akses (Panduan Pemrograman C#).
Blazor Kerangka kerja memproses komponen secara internal sebagai pohon render, yang merupakan kombinasi dari DOM komponen dan Model Objek Lembar Gaya Kaskading (CSSOM). Setelah komponen awalnya dirender, pohon render komponen dibuat ulang sebagai respons terhadap peristiwa. Blazor membandingkan pohon render baru dengan pohon render sebelumnya dan menerapkan modifikasi apa pun ke DOM browser untuk ditampilkan. Untuk informasi lebih lanjut, lihat perenderan komponen Razor ASP.NET Core.
Sintaks Razor untuk struktur kontrol C#, arahan, dan atribut arahan adalah huruf kecil (misalnya: @if
, @code
, @bind
). Nama properti adalah huruf besar (misalnya: @Body
untuk LayoutComponentBase.Body).
Metode asinkron (async
) tidak mendukung pengembalian void
Kerangka kerja Blazor tidak melacak metode asinkron yang mengembalikan void
(async
). Akibatnya, pengecualian tidak ditangkap jika void
dikembalikan. Selalu kembalikan Task dari metode asinkron.
Komponen yang disarangkan
Komponen dapat menyertakan komponen lain dengan mendeklarasikannya menggunakan sintaks HTML. Markup untuk menggunakan komponen terlihat seperti tag HTML di mana nama tag adalah jenis komponennya.
Perhatikan komponen Heading
berikut, yang dapat digunakan oleh komponen lain untuk menampilkan judul.
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";
}
Markup berikut dalam komponen HeadingExample
merender komponen Heading
sebelumnya di lokasi munculnya tag <Heading />
.
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 />
Jika komponen berisi elemen HTML dengan huruf pertama yang ditulis dalam huruf besar, yang tidak cocok dengan nama komponen dalam namespace layanan yang sama, akan muncul peringatan yang menunjukkan bahwa elemen tersebut memiliki nama yang tidak terduga. Menambahkan arahan @using
untuk namespace layanan komponen membuat komponen tersedia, yang akan menyelesaikan peringatan tersebut. Untuk informasi selengkapnya, lihat bagian Nama komponen , nama kelas, dan namespace layanan.
Contoh komponen Heading
yang ditampilkan di bagian ini tidak memiliki arahan @page
, sehingga komponen Heading
tidak dapat diakses secara langsung oleh pengguna melalui permintaan langsung di browser. Namun, komponen apa pun dengan arahan @page
dapat disarangkan di komponen lain. Jika komponen Heading
dapat diakses secara langsung dengan menyertakan @page "/heading"
di bagian atas file Razor-nya, maka komponen tersebut akan dirender untuk permintaan browser di /heading
dan /heading-example
.
Parameter komponen
Parameter komponen meneruskan data ke komponen dan ditentukan menggunakan properti C# publik pada kelas komponen dengan atribut [Parameter]
. Dalam contoh berikut, jenis referensi bawaan (System.String) dan jenis referensi yang ditentukan pengguna (PanelBody
) diteruskan sebagai parameter komponen.
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">
@Body.Text
</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"
};
}
<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">
@Body.Text
</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"
};
}
<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">
@Body.Text
</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"
};
}
<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">
@Body.Text
</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"
};
}
<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">
@Body.Text
</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"
};
}
<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">
@Body.Text
</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"
};
}
Peringatan
Memberikan nilai awal untuk parameter komponen didukung, tetapi jangan membuat komponen yang menulis ke parameternya sendiri setelah komponen dirender untuk pertama kalinya. Untuk informasi selengkapnya, lihat Menghindari penimpaan parameter di ASP.NET Core Blazor.
Parameter komponen Title
dan Body
dari komponen ParameterChild
ditetapkan oleh argumen dalam tag HTML yang merender instans komponen. Komponen ParameterParent
berikut merender dua komponen ParameterChild
:
- Komponen
ParameterChild
pertama dirender tanpa memberikan argumen parameter. - Komponen
ParameterChild
kedua menerima nilai untukTitle
danBody
dari komponenParameterParent
, yang menggunakan ekspresi C# eksplisit untuk mengatur nilai propertiPanelBody
.
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" })" />
Markup HTML yang dirender berikut dari komponen ParameterParent
menunjukkan nilai default komponen ParameterChild
jika komponen ParameterParent
tidak menyediakan nilai parameter komponen. Saat komponen ParameterParent
memberikan nilai parameter komponen, komponen tersebut menggantikan nilai default komponen ParameterChild
.
Catatan
Untuk lebih jelasnya, kelas gaya CSS yang dirender tidak ditampilkan dalam markup HTML yang dirender berikut.
<h1>Child component (without attribute values)</h1>
<div>
<div>Set By Child</div>
<div>Set by child.</div>
</div>
<h1>Child component (with attribute values)</h1>
<div>
<div>Set by Parent</div>
<div>Set by parent.</div>
</div>
Tetapkan bidang C#, properti, atau hasil metode ke parameter komponen sebagai nilai atribut HTML. Nilai atribut biasanya dapat berupa ekspresi C# apa pun yang cocok dengan jenis parameter. Nilai atribut dapat secara opsional mengarah dengan simbol yang Razor dipesan@
, tetapi tidak diperlukan.
Jika parameter komponen adalah jenis string, maka nilai atribut malah diperlakukan sebagai string C# literal. Jika Anda ingin menentukan ekspresi C#, maka gunakan awalan @
.
Komponen ParameterParent2
berikut menampilkan empat instans komponen ParameterChild
sebelumnya dan mengatur nilai parameter Title
ke:
- Nilai bidang
title
. - Hasil dari metode C#
GetTitle
. - Tanggal lokal saat ini dalam format panjang dengan ToLongDateString, yang menggunakan ekspresi C# implisit.
- Properti
Title
objekpanelData
.
Kutipan di sekitar nilai atribut parameter bersifat opsional dalam banyak kasus sesuai spesifikasi HTML5. Misalnya, Value=this
didukung, alih-alih Value="this"
. Namun, sebaiknya gunakan tanda kutip karena lebih mudah diingat dan diadopsi secara luas di seluruh teknologi berbasis web.
Sepanjang dokumentasi, contoh kode:
- Selalu menggunakan kutipan. Contoh:
Value="this"
. - Jangan gunakan awalan
@
dengan nonliteral kecuali diperlukan. Contoh:Count="ct"
, di manact
adalah variabel berjenis angka.Count="@ct"
adalah pendekatan gaya yang valid, tetapi dokumentasi dan contoh tidak mengadopsi konvensi. - Selalu hindari
@
untuk harfiah, di luar Razor ekspresi. Contoh:IsFixed="true"
. Ini termasuk kata kunci (misalnya,this
) dannull
, tetapi Anda dapat memilih untuk menggunakannya jika Anda mau. Misalnya,IsFixed="@true"
tidak umum tetapi didukung.
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" />
@code {
private string title = "From Parent field";
private PanelData panelData = new();
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" />
@code {
private string title = "From Parent field";
private PanelData panelData = new();
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" />
@code {
private string title = "From Parent field";
private PanelData panelData = new();
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" />
@code {
private string title = "From Parent field";
private PanelData panelData = new();
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" />
@code {
private string title = "From Parent field";
private PanelData panelData = new PanelData();
private string GetTitle()
{
return "From Parent method";
}
private class PanelData
{
public string Title { get; set; } = "From Parent object";
}
}
Catatan
Saat menetapkan anggota C# ke parameter komponen, jangan awali atribut HTML parameter dengan @
.
Benar (Title
adalah parameter string, Count
adalah parameter berjenis angka):
<ParameterChild Title="@title" Count="ct" />
<ParameterChild Title="@title" Count="@ct" />
Salah:
<ParameterChild @Title="@title" @Count="ct" />
<ParameterChild @Title="@title" @Count="@ct" />
Tidak seperti di halaman Razor (.cshtml
), Blazor tidak dapat melakukan pekerjaan asinkron dalam ekspresi Razor saat merender komponen. Ini karena Blazor dirancang untuk merender antarmuka pengguna interaktif. Dalam antarmuka pengguna interaktif, layar harus selalu menampilkan sesuatu, jadi tidak masuk akal untuk memblokir aliran perenderan. Sebagai gantinya, pekerjaan asinkron dilakukan selama salah satu peristiwa siklus hidup asinkron. Setelah setiap peristiwa siklus hidup asinkron, komponen dapat merender lagi. Sintaks Razor berikut tidak didukung:
<ParameterChild Title="await ..." />
<ParameterChild Title="@await ..." />
Kode dalam contoh sebelumnya menghasilkan kesalahan kompilator saat aplikasi dibangun:
Operator 'await' hanya dapat digunakan dalam metode asinkron. Pertimbangkan untuk menandai metode ini dengan pengubah 'async' dan mengubah jenis pengembaliannya menjadi 'Task'.
Untuk mendapatkan nilai parameter Title
dalam contoh sebelumnya secara asinkron, komponen dapat menggunakan peristiwa siklus hidup OnInitializedAsync
, seperti yang ditunjukkan contoh berikut:
<ParameterChild Title="@title" />
@code {
private string? title;
protected override async Task OnInitializedAsync()
{
title = await ...;
}
}
Untuk informasi lebih lanjut, lihat siklus hidup komponen Razor ASP.NET Core.
Penggunaan ekspresi Razor eksplisit untuk menggabungkan teks dengan hasil ekspresi untuk penetapan ke parameter tidak didukung. Contoh berikut berupaya menggabungkan teks "Set by
" dengan nilai properti objek. Meskipun sintaks ini didukung di halaman Razor (.cshtml
), sintaks ini tidak valid untuk penetapan parameter Title
turunan dalam suatu komponen. Sintaks Razor berikut tidak didukung:
<ParameterChild Title="Set by @(panelData.Title)" />
Kode dalam contoh sebelumnya menghasilkan kesalahan kompilator saat aplikasi dibangun:
Atribut komponen tidak mendukung konten yang kompleks (campuran C# dan markup).
Untuk mendukung penetapan nilai yang tersusun, gunakan metode, bidang, atau properti. Contoh berikut melakukan penggabungan "Set by
" dan nilai properti objek dalam metode C# 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";
}
}
Untuk informasi lebih lanjut, lihat Referensi sintaks Razor untuk ASP.NET Core.
Peringatan
Memberikan nilai awal untuk parameter komponen didukung, tetapi jangan membuat komponen yang menulis ke parameternya sendiri setelah komponen dirender untuk pertama kalinya. Untuk informasi selengkapnya, lihat Menghindari penimpaan parameter di ASP.NET Core Blazor.
Parameter komponen harus dideklarasikan sebagai auto-properties, artinya parameter tersebut tidak boleh berisi logika kustom di pengakses get
atau set
-nya. Misalnya, properti StartData
berikut adalah properti otomatis:
[Parameter]
public DateTime StartData { get; set; }
Jangan tempatkan logika kustom di pengakses get
atau set
karena parameter komponen murni dimaksudkan untuk digunakan sebagai saluran bagi komponen induk untuk mengalirkan informasi ke komponen turunan. Jika pengakses set
dari properti komponen turunan berisi logika yang menyebabkan perenderan ulang komponen induk, makan akan menyebabkan perulangan perenderan tak terbatas.
Untuk mengubah nilai parameter yang diterima:
- Biarkan properti parameter sebagai properti otomatis untuk mewakili data mentah yang disediakan.
- Buat properti atau metode yang berbeda untuk menyediakan data yang diubah berdasarkan properti parameter.
Timpa OnParametersSetAsync
untuk mengubah parameter yang diterima setiap kali data baru diterima.
Penulisan nilai awal ke parameter komponen didukung karena penetapan nilai awal tidak mengganggu perenderan komponen otomatis Blazor. Penetapan DateTime lokal saat ini dengan DateTime.Now ke StartData
berikut adalah sintaks yang valid dalam sebuah komponen:
[Parameter]
public DateTime StartData { get; set; } = DateTime.Now;
Setelah penetapan awal DateTime.Now, jangan menetapkan nilai ke StartData
dalam kode pengembang. Untuk informasi selengkapnya, lihat Menghindari penimpaan parameter di ASP.NET Core Blazor.
Terapkan atribut [EditorRequired]
untuk menentukan parameter komponen yang diperlukan. Jika nilai parameter tidak diberikan, editor atau alat build dapat menampilkan peringatan kepada pengguna. Atribut ini hanya valid pada properti yang juga ditandai dengan atribut [Parameter]
. EditorRequiredAttribute diberlakukan pada waktu desain dan saat aplikasi dibangun. Atribut tidak diberlakukan pada runtime bahasa umum, dan tidak menjamin nilai parameter non-null
.
[Parameter]
[EditorRequired]
public string? Title { get; set; }
Daftar atribut satu baris juga didukung:
[Parameter, EditorRequired]
public string? Title { get; set; }
Jangan gunakan pengubah required
atau init
aksesor pada properti parameter komponen. Komponen biasanya dibuat dan ditetapkan nilai parameter menggunakan pantulan, yang melewati jaminan yang init
dan required
dirancang untuk dibuat. Sebagai gantinya [EditorRequired]
, gunakan atribut untuk menentukan parameter komponen yang diperlukan.
Jangan gunakan init
aksesor pada properti parameter komponen karena mengatur nilai parameter komponen dengan ParameterView.SetParameterProperties menggunakan pantulan, yang melewati pembatasan setter init-only. [EditorRequired]
Gunakan atribut untuk menentukan parameter komponen yang diperlukan.
Jangan gunakan init
aksesor pada properti parameter komponen karena mengatur nilai parameter komponen dengan ParameterView.SetParameterProperties menggunakan pantulan, yang melewati pembatasan setter init-only.
Tuples
(dokumentasi API) didukung untuk parameter komponen dan jenis RenderFragment
. Contoh parameter komponen berikut meneruskan tiga nilai dalam 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);
}
Tuple bernama didukung, seperti yang terlihat dalam contoh berikut:
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);
}
Quote ©2005 Universal Pictures: Serenity (Nathan Fillion)
Tuples
(dokumentasi API) didukung untuk parameter komponen dan jenis RenderFragment
. Contoh parameter komponen berikut meneruskan tiga nilai dalam 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);
}
Tuple bernama didukung, seperti yang terlihat dalam contoh berikut:
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);
}
Quote ©2005 Universal Pictures: Serenity (Nathan Fillion)
Tuples
(dokumentasi API) didukung untuk parameter komponen dan jenis RenderFragment
. Contoh parameter komponen berikut meneruskan tiga nilai dalam 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);
}
Tuple bernama didukung, seperti yang terlihat dalam contoh berikut:
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);
}
Quote ©2005 Universal Pictures: Serenity (Nathan Fillion)
Parameter rute
Komponen dapat menentukan parameter rute dalam template rute dari arahan @page
. Router Blazor menggunakan parameter rute untuk mengisi parameter komponen yang sesuai.
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; }
}
Untuk informasi selengkapnya, lihat bagian Parameter rute dari perutean dan navigasi inti Blazor ASP.NET. Parameter rute opsional juga didukung dan dibahas di bagian yang sama. Untuk informasi tentang parameter rute catch-all ({*pageRoute}
), yang mengambil jalur di beberapa batas folder, lihat bagian Parameter rute Catch-all dari perutean dan navigasi Inti Blazor ASP.NET.
Untuk informasi selengkapnya, lihat bagian Parameter rute dari perutean dan navigasi inti Blazor ASP.NET. Parameter rute opsional tidak didukung, jadi diperlukan dua @page
arahan (lihat bagian Parameter rute untuk informasi selengkapnya). Untuk informasi tentang parameter rute catch-all ({*pageRoute}
), yang mengambil jalur di beberapa batas folder, lihat bagian Parameter rute Catch-all dari perutean dan navigasi Inti Blazor ASP.NET.
Peringatan
Dengan kompresi, yang diaktifkan secara default, hindari membuat komponen sisi server interaktif yang aman (diautentikasi/diotorisasi) yang merender data dari sumber yang tidak tepercaya. Sumber yang tidak tepercaya termasuk parameter rute, string kueri, data dari JS interop, dan sumber data lain yang dapat dikontrol pengguna pihak ketiga (database, layanan eksternal). Untuk informasi selengkapnya, lihat panduan inti BlazorSignalR ASP.NET dan panduan mitigasi ancaman untuk penyajian sisi server interaktif ASP.NET CoreBlazor.
Fragmen render konten turunan
Komponen dapat mengatur isi dari komponen lain. Komponen penetapan menyediakan konten antara tag pembuka dan penutup komponen turunan.
Dalam contoh berikut, komponen RenderFragmentChild
memiliki parameter komponen ChildContent
yang mewakili segmen antarmuka pengguna untuk dirender sebagai RenderFragment. Posisi ChildContent
dalam markup Razor komponen adalah tempat konten dirender dalam output HTML akhir.
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; }
}
Penting
Properti yang menerima konten RenderFragment harus diberi nama ChildContent
berdasarkan konvensi.
Panggilan balik peristiwa tidak didukung untuk RenderFragment.
Komponen berikut menyediakan konten untuk merender RenderFragmentChild
dengan menempatkan konten di dalam tag pembukaan dan penutup komponen anak.
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>
Fragmen render digunakan untuk merender konten turunan di seluruh aplikasi Blazor dan dijelaskan dengan contoh di artikel dan bagian artikel berikut:
- Tata letak Blazor
- Meneruskan data di seluruh hierarki komponen
- Komponen bersalur
- Penanganan pengecualian global
Catatan
Komponen Razor bawaan kerangka kerja Blazor menggunakan konvensi parameter komponen ChildContent
yang sama untuk mengatur kontennya. Anda dapat melihat komponen yang mengatur konten turunan dengan mencari ChildContent
nama properti parameter komponen di dokumentasi API (memfilter API dengan istilah pencarian "ChildContent").
Merender fragmen untuk logika perenderan yang dapat digunakan kembali
Anda dapat memfaktorkan komponen turunan murni sebagai cara untuk menggunakan kembali logika perenderan. Di blok @code
komponen mana pun, tentukan RenderFragment dan render fragmen dari lokasi mana pun sebanyak yang diperlukan:
@RenderWelcomeInfo
<p>Render the welcome info a second time:</p>
@RenderWelcomeInfo
@code {
private RenderFragment RenderWelcomeInfo = @<p>Welcome to your new app!</p>;
}
Untuk informasi lebih lanjut, lihat Menggunakan kembali logika perenderan.
Variabel perulangan dengan parameter komponen dan konten turunan
Komponen penyajian di dalam for
perulangan memerlukan variabel indeks lokal jika variabel perulangan yang bertambah banyak digunakan oleh parameter komponen atau RenderFragment konten turunan.
Pertimbangkan komponen berikut RenderFragmentChild2
yang memiliki parameter komponen (Id
) dan fragmen render untuk menampilkan konten anak (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; }
}
Saat merender RenderFragmentChild2
komponen dalam komponen induk, gunakan variabel indeks lokal (ct
dalam contoh berikut) alih-alih variabel perulangan (c
) saat menetapkan nilai parameter komponen dan menyediakan konten komponen anak:
@for (int c = 1; c < 4; c++)
{
var ct = c;
<RenderFragmentChild2 Id="@($"Child{ct}")">
Count: @ct
</RenderFragmentChild2>
}
Atau, gunakan perulangan foreach
dengan Enumerable.Range alih-alih perulangan for
:
@foreach (var c in Enumerable.Range(1, 3))
{
<RenderFragmentChild2 Id="@($"Child{c}")">
Count: @c
</RenderFragmentChild2>
}
Mengambil referensi ke komponen
Referensi komponen menyediakan cara untuk mereferensikan instans komponen untuk mengeluarkan perintah. Untuk mengambil referensi komponen:
- Tambahkan atribut
@ref
ke komponen turunan. - Tentukan bidang dengan jenis yang sama dengan komponen turunan.
Saat komponen dirender, bidang diisi dengan instans komponen. Anda kemudian dapat memanggil metode .NET pada instans.
Pertimbangkan komponen ReferenceChild
berikut yang mencatat pesan saat ChildMethod
-nya dipanggil.
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);
}
}
Referensi komponen hanya diisi setelah komponen dirender dan outputnya menyertakan elemen ReferenceChild
. Sampai komponen dirender, tidak ada referensi apa pun. Jangan mencoba memanggil metode komponen yang direferensikan ke penanganan aktivitas secara langsung (misalnya, @onclick="childComponent!.ChildMethod(5)"
) karena variabel referensi mungkin tidak ditetapkan pada saat peristiwa klik ditetapkan.
Untuk memanipulasi referensi komponen setelah komponen selesai dirender, gunakan metode OnAfterRender
atau OnAfterRenderAsync
.
Contoh berikut menggunakan komponen sebelumnya ReferenceChild
.
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);
}
}
Meskipun pengambilan referensi komponen menggunakan sintaks yang mirip dengan pengambilan referensi elemen, pengambilan referensi komponen bukanlah fitur interop JavaScript. Referensi komponen tidak diteruskan ke kode JavaScript. Referensi komponen hanya digunakan dalam kode .NET.
Penting
Jangan menggunakan referensi komponen untuk mengubah status komponen turunan. Sebagai gantinya, gunakan parameter komponen deklaratif normal untuk meneruskan data ke komponen turunan. Penggunaan parameter komponen menyebabkan komponen turunan yang dirender ulang pada waktu yang tepat secara otomatis. Untuk informasi lebih lanjut, lihat bagian parameter komponen dan artikel pengikatan data Blazor ASP.NET Core.
Menerapkan atribut
Atribut dapat diterapkan ke komponen dengan arahan @attribute
. Contoh berikut menerapkan atribut [Authorize]
ke kelas komponen:
@page "/"
@attribute [Authorize]
Atribut elemen HTML bersyar dan properti DOM
Blazor mengadopsi perilaku umum berikut:
- Untuk atribut HTML, Blazor atur atau hapus atribut secara kondisional berdasarkan nilai .NET. Jika nilai .NET adalah
false
ataunull
, atribut tidak diatur atau dihapus jika sebelumnya diatur. - Untuk properti DOM, seperti
checked
atauvalue
, Blazor mengatur properti DOM berdasarkan nilai .NET. Jika nilai .NET adalahfalse
ataunull
, properti DOM diatur ulang ke nilai default.
Atribut sintaks mana Razor yang sesuai dengan atribut HTML dan mana yang sesuai dengan properti DOM tetap tidak terdokumentasi karena ini adalah detail implementasi kerangka kerja yang mungkin berubah tanpa pemberitahuan.
Peringatan
Beberapa atribut HTML, seperti aria-pressed
, harus memiliki nilai string "true" atau "false". Karena memerlukan nilai string dan bukan boolean, Anda harus menggunakan .NET string
dan bukan bool
untuk nilainya. Ini adalah persyaratan yang ditetapkan oleh API DOM browser.
HTML mentah
String biasanya dirender menggunakan node teks DOM, yang berarti bahwa markup apa pun yang dikandungnya akan diabaikan dan diperlakukan sebagai teks harfiah. Untuk merender HTML mentah, bungkus konten HTML dalam nilai MarkupString. Nilai diurai sebagai HTML atau SVG dan disisipkan ke dalam DOM.
Peringatan
Perenderan HTML mentah yang dibuat dari sumber yang tidak tepercaya merupakan risiko keamanan dan harus selalu dihindari.
Contoh berikut menunjukkan penggunaan jenis MarkupString untuk menambahkan blok konten HTML statis ke output komponen yang dirender.
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>";
}
Template Razor
Fragmen render dapat ditentukan menggunakan sintaks template Razor untuk menentukan cuplikan antarmuka pengguna. Template Razor menggunakan format berikut:
@<{HTML tag}>...</{HTML tag}>
Contoh berikut mengilustrasikan cara menentukan nilai RenderFragment dan RenderFragment<TValue> serta merender template secara langsung dalam komponen. Render fragmen juga dapat diteruskan sebagai argumen ke komponen template.
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; }
}
}
Output yang dirender dari kode sebelumnya:
<p>The time is 4/19/2021 8:54:46 AM.</p>
<p>Pet: Nutty Rex</p>
Aset statis
Blazor mengikuti konvensi aplikasi ASP.NET Core untuk aset statis. Aset statis terletak di folder web root
(wwwroot
) proyek atau folder di bawah folder wwwroot
.
Gunakan jalur relatif dasar (/
) guna merujuk ke akar web untuk aset statis. Dalam contoh berikut, logo.png
secara fisik terletak di folder {PROJECT ROOT}/wwwroot/images
. {PROJECT ROOT}
adalah akar proyek aplikasi.
<img alt="Company logo" src="/images/logo.png" />
Komponen tidak mendukung notasi tilde-slash (~/
).
Untuk informasi tentang mengatur jalur dasar aplikasi, lihat Menghosting dan menyebarkan Blazor ASP.NET Core.
Pembantu Tag tidak didukung di komponen
Tag Helpers
tidak didukung dalam komponen. Untuk menyediakan fungsionalitas seperti Pembantu Tag di Blazor, buat komponen dengan fungsi yang sama seperti Pembantu Tag dan gunakan komponen sebagai gantinya.
Gambar Scalable Vector Graphics (SVG)
Karena Blazor merender HTML, gambar yang didukung browser, termasuk gambar Scalable Vector Graphics (SVG) (.svg
), didukung melalui tag <img>
:
<img alt="Example image" src="image.svg" />
Demikian pula, gambar SVG didukung dalam aturan CSS dari file lembar gaya (.css
):
.element-class {
background-image: url("image.svg");
}
Blazor mendukung elemen <foreignObject>
untuk menampilkan HTML arbitrer dalam SVG. Markup dapat mewakili HTML arbitrer, RenderFragment, atau komponen Razor.
Contoh berikut menunjukkan:
- Tampilan
string
(@message
). - Pengikatan dua arah dengan elemen
<input>
dan bidangvalue
. - Komponen
Robot
.
<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;
}
Perilaku perenderan spasi kosong
Kecuali direktif @preservewhitespace
digunakan dengan nilai true
, spasi kosong tambahan dihapus jika:
- Di depan atau di belakang dalam elemen.
- Di depan atau di belakang dalam parameter RenderFragment/RenderFragment<TValue> (misalnya, konten turunan diteruskan ke komponen lain).
- Ini mendahului atau mengikuti blok kode C#, seperti
@if
atau@foreach
.
Penghapusan spasi kosong dapat memengaruhi output yang dirender saat menggunakan aturan CSS, seperti white-space: pre
. Untuk menonaktifkan pengoptimalan performa ini dan mempertahankan spasi kosong, lakukan salah satu tindakan berikut:
- Tambahkan arahan
@preservewhitespace true
di bagian atas file Razor (.razor
) untuk menerapkan preferensi ke komponen tertentu. - Tambahkan arahan
@preservewhitespace true
di dalam file_Imports.razor
untuk menerapkan preferensi ke subdirektori atau ke seluruh proyek.
Dalam kebanyakan kasus, tidak ada tindakan yang diperlukan, karena aplikasi biasanya terus berperilaku normal (tetapi lebih cepat). Jika menghapus spasi kosong menyebabkan masalah perenderan untuk komponen tertentu, gunakan @preservewhitespace true
dalam komponen tersebut untuk menonaktifkan pengoptimalan ini.
Spasi kosong dipertahankan dalam markup sumber komponen. Teks khusus spasi kosong dirender di DOM browser meskipun tidak ada efek visual.
Pertimbangkan markup komponen berikut:
<ul>
@foreach (var item in Items)
{
<li>
@item.Text
</li>
}
</ul>
Contoh sebelumnya merender spasi kosong yang tidak perlu berikut ini:
- Di luar blok kode
@foreach
. - Di sekitar elemen
<li>
. - Di sekitar output
@item.Text
.
Daftar 100 item menghasilkan lebih dari 400 area spasi kosong. Tidak satu pun dari spasi kosong ekstra yang secara visual memengaruhi output yang dirender.
Saat merender HTML statis untuk komponen, spasi kosong di dalam tag tidak dipertahankan. Misalnya, lihat output yang dirender dari tag <img>
berikut dalam file Razor komponen (.razor
):
<img alt="Example image" src="img.png" />
Spasi kosong tidak dipertahankan dari markup sebelumnya:
<img alt="Example image" src="img.png" />
Komponen akar
Komponen akar Razor (komponen akar) adalah komponen pertama yang dimuat dari hierarki komponen apa pun yang dibuat oleh aplikasi.
Dalam aplikasi yang dibuat dari Blazor Web App templat proyek, App
komponen (App.razor
) ditentukan sebagai komponen akar default oleh parameter jenis yang dideklarasikan untuk panggilan ke MapRazorComponents<TRootComponent>
dalam file sisi Program
server. Contoh berikut menunjukkan penggunaan App
komponen sebagai komponen akar, yang merupakan default untuk aplikasi yang dibuat dari Blazor templat proyek:
app.MapRazorComponents<App>();
Catatan
Membuat komponen akar interaktif, seperti App
komponen, tidak didukung.
Dalam aplikasi yang dibuat dari Blazor Server templat proyek, App
komponen (App.razor
) ditentukan sebagai komponen akar default dalam Pages/_Host.cshtml
menggunakan Bantuan Tag Komponen:
<component type="typeof(App)" render-mode="ServerPrerendered" />
Dalam aplikasi yang dibuat dari Blazor WebAssembly templat proyek, App
komponen (App.razor
) ditentukan sebagai komponen akar default dalam Program
file:
builder.RootComponents.Add<App>("#app");
Dalam kode sebelumnya, pemilih CSS, #app
, menunjukkan bahwa App
komponen ditentukan untuk <div>
masuk wwwroot/index.html
dengan id
dari app
:
<div id="app">...</app>
Aplikasi MVC dan Razor Pages juga dapat menggunakan Pembantu Tag Komponen untuk mendaftarkan komponen akar yang dirender Blazor WebAssembly secara statis:
<component type="typeof(App)" render-mode="WebAssemblyPrerendered" />
Komponen yang dirender secara statis hanya dapat ditambahkan ke aplikasi. Mereka tidak dapat dihapus atau diperbarui setelahnya.
Untuk informasi selengkapnya, lihat sumber daya berikut:
ASP.NET Core