-
Blazor Components
- infrastructural
- Routing
-
parameters
- Component parameters
- routing parameter
- life cycle event
- Status Changes
- Component Events
Blazor Components
infrastructural
Create a new project named MyComponents, select Auto for the interaction type of the project template, and leave the other options as default:
client component (Auto/WebAssembly):
There will be two items inside the final solution:Server-side projects、Client projects, components can be categorized into the following two types of components according to the storage items:
-
server-side component:
- Primarily for server-side rendering (SSR)
- Being placed in a server-side project
- For scenarios that do not require real-time interaction or complex user interaction
-
client component (Auto/WebAssembly):
- Components are located within the client project
- Compiled using WebAssembly technology and able to interact directly with the browser
- Ideal for application scenarios that require interactivity and real-time updates
- Using SignalR enables real-time communication to enhance the functionality of your components.
The two component selection principles are as follows.
- If the component doesn't require interactivity, use it as theserver-side renderingThe components of the
- If the component requires interactivity (e.g., responding to user input, real-time data updates, etc.), it should be considered as theclient componentThe SignalR provides real-time communication capabilities that can be utilized in a variety of ways.
Create a new Demo component in the client project:
<!-- option Auto maybe WebAssembly ,Otherwise, no interaction is possible -->
@rendermode InteractiveAuto
<h3>Demo</h3>
<!-- Show labels only when text is not empty -->
@if (textInfo is not null)
{
<h4>Info: @textInfo</h4>
}
<!-- Button Style Reference Counter subassemblies -->
<button class="btn btn-primary" @onclick="UpdateText">Update Text</button>
<!-- Invoking methods by delegation,You can pass in the parameter -->
<button class="btn btn-primary" @onclick="(()=>{UpdateNumber(10);})">Update Number</button>
@code {
private string? textInfo = null;
private void UpdateText()
{
textInfo = "This is the new information";
}
private void UpdateNumber(int i = 0)
{
textInfo = $"This is number {i}";
}
}
Reference the Demo component in the Home page of the server-side project:
@page "/"
<PageTitle>Home</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<Demo />
Reference the namespace of the Demo component in _Imports.razor:
@using
Routing
Add a Start component to the client project with the following razor code:
@*Components can have multiple routes at the same time *@
@page "/page"
@page "/pages/start"
@*Component names can be used as routes**@
@attribute [Route(nameof(Start))]
@*Page jumps must specify interactivity and inject a navigation manager *@
@rendermode InteractiveAuto
@inject NavigationManager Navigation
<h3> Start</h3>
@*Jump to Counter component via method *@
<button class="btn btn-primary" onclick="@(()=>(nameof(Counter)))">Go to Counter</button>
@* Perform a full page reload *@
<button class="btn btn-primary" onclick="@(()=>(true))">Refresh</button>
@code {
}
The code above demonstrates how to make a page jump using a route and navigation manager.Components can have multiple routes at the same time, or you can use the component name as a route。
Used when jumping to other componentsEnhanced NavigationreferenceEnhanced navigation and form handling 。
parameters
Component parameters
Add a BetterCounter component to the client project with the following razor code:
@rendermode InteractiveAuto
<h3>BetterCounter</h3>
<p role="status">Current count: @CurrentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
//Representation of target members as component parameters
[Parameter]
public int CurrentCount { get; set; }
private void IncrementCount()
{
CurrentCount++;
}
}
Component parameters pass data to the component, and are defined using public C# properties in the component class that contain the [Parameter] featurereferenceComponent parameters cap (a poem)one-way binding 。
When using a component, you need to pass the target member as a component parameter to the component, such as referencing the BetterCounter component on the Home page:
<BetterCounter CurrentCount="100" />
<!-- maybe -->
<BetterCounter CurrentCount=@currentCount />
routing parameter
The router uses routing parametersFill the corresponding component parameter with the same name, the route parameter name is not case-sensitiveReference Documentationrouting parameter 。
Add the following route to the razor code of the BetterCounter component:
@*Routing Parameters (Unconstrained) *@
@page "/BetterCounter/{CurrentCount}"
@*Routing parameter constraints *@
@page "/BetterCounter/{CurrentCount:int}"
@*Optional Route Parameters (use with any of the above routes to achieve optional effects)*@
@page "/BetterCounter"
In order to implement optional routing parameters, a default value needs to be added to the component:
// Represent the target member as a component parameter
// Need to change the type of the parameter attribute to nullable so you can tell if it's been assigned a value or not
[Parameter]
public int? CurrentCount { get; set; }
//Specify default values for optional parameters
protected override void OnInitialized()
{
(); }//Specify the default value for the optional parameter.
CurrentCount = CurrentCount ? 1; }
}
Add a Titlet member to accept query string arguments:
// Specify that the component parameters come from the query string
//Route:/BetterCounter?Titlet=asd
[SupplyParameterFromQuery]
public string? Titlet { get; set; } = "BetterCounter".
-
routing parameter: In the add component's@page declaration by enclosing the names of the routing parameters in a pair of{ curly brackets } In the example, the routing parameters are defined in the URL, refer to the samplerouting parameter 。
-
Routing Parameter Constraints: suffixed by a colon, followed by the constraint type, constraint type reference documentationrouting constraint。
routing (computing)/BetterCounter/abs As an example:- Type conversion exceptions are reported when there are no routing constraints (strings cannot be converted to int types)
- A 404 error is displayed when there is a route constraint (no match for the URL)
-
Optional Routing Parameters:BlazorOptional routing parameters are not explicitly supported, but by adding multiple@page Statement that equivalent routing parameters can be easily implemented, refer to the articleOptional Routing Parameters。
-
query string: Use[SupplyParameterFromQuery] attribute specifies that the component parameter comes from a query string, see the documentation for more application scenarios.query string。
life cycle event
The following simplified diagram shows the Razor component lifecycle event handling, referring to the documentationlife cycle event:
Add logging to the Counter component to observe the component's lifecycle:
@inject ILogger<Counter> log
//...
@code {
//...
protected override void OnInitialized()
{
($"Initialized at {}");
}
protected override void OnParametersSet()
{
($"ParametersSet at {}");
}
protected override void OnAfterRender(bool firstRender)
{
("OnAfterRender: firstRender = {FirstRender}", firstRender);
}
}
-
Component Initialization (OnInitialized{Async}) : Specialized for initializing components throughout the life cycle of a component instance, parameter values and parameter value changes should not affect the initialization performed in these methods.
-
After setting the parameters (OnParametersSet{Async}): Called after initializing the component in OnInitialized or OnInitializedAsync or when the parent component is re-presented with changed parameters.
-
After component rendering (OnAfterRender{Async}): The OnAfterRender and OnAfterRenderAsync components are rendered interactively and called after the UI has been updated (e.g., after an element has been added to the browser's DOM).firstRender Parameters:
- Set to true the first time a component instance is rendered.
- can be used to ensure that the initialization operation is performed only once.
After running and navigating to the Counter screen, the console output is as follows:
Status Changes
StateHasChanged Notifies the component that its status has changed. If applicable.Calling StateHasChanged causes the component to be re-rendered.。
StateHasChanged will be called automatically for the EventCallback method, or you can call StateHasChanged manually in the component as needed:
private async void IncrementCount()
{
currentCount++;
await (1000);
StateHasChanged();
currentCount++;
await (1000);
StateHasChanged();
currentCount++;
await (1000);
StateHasChanged();
}
If you don't call StateHasChanged, only the first and the last value will show 1 when you click on it, but if you use StateHasChanged, it will show 1, 2 and 3 in turn.
Component Events
A common scheme for nesting components isExecute a method in the parent component when a child component event occurs(e.g., the onclick event in a subcomponent), and to expose events across components, use theEventCallback The parent component can assign callback methods to the child component's EventCallback.
Add an event to the Counter component:
@code {
private int currentCount = 0;
//Define an event callback parameter
[Parameter]
public EventCallback<int> OnCounterChange { get; set; }
private async Task IncrementCount()
{
currentCount++;
//trigger event callback
await (currentCount);
}
}
Assign callback methods to the Counter component's events in another client-side component (the server-side component will report an error):
<Counter OnCounterChange="UpdateCounter" />
@code {
private int currentCount = 0;
private void UpdateCounter(int val)
{
currentCount = val;
}
}