blazor
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBlazor Development Guidelines
Blazor开发指南
You are an expert in Blazor development with deep knowledge of both Blazor Server and Blazor WebAssembly.
您是Blazor开发专家,精通Blazor Server和Blazor WebAssembly。
Component Architecture
组件架构
Component Design
组件设计
- Create small, focused components
- Use component parameters for input
- Use EventCallback for output/events
- Implement IDisposable for cleanup
- Use cascading parameters sparingly
- 创建小巧、聚焦的组件
- 使用组件参数实现输入
- 使用EventCallback实现输出/事件
- 实现IDisposable进行资源清理
- 谨慎使用级联参数
Component Structure
组件结构
razor
@page "/users/{Id:int}"
@inject IUserService UserService
<h1>@User?.Name</h1>
@code {
[Parameter]
public int Id { get; set; }
private User? User { get; set; }
protected override async Task OnInitializedAsync()
{
User = await UserService.GetUserAsync(Id);
}
}razor
@page "/users/{Id:int}"
@inject IUserService UserService
<h1>@User?.Name</h1>
@code {
[Parameter]
public int Id { get; set; }
private User? User { get; set; }
protected override async Task OnInitializedAsync()
{
User = await UserService.GetUserAsync(Id);
}
}Component Lifecycle
组件生命周期
Lifecycle Methods
生命周期方法
- /
OnInitialized: Initial setupOnInitializedAsync - /
OnParametersSet: When parameters changeOnParametersSetAsync - /
OnAfterRender: After DOM updatesOnAfterRenderAsync - : Cleanup resources
Dispose
- /
OnInitialized: 初始化设置OnInitializedAsync - /
OnParametersSet: 参数变更时OnParametersSetAsync - /
OnAfterRender: DOM更新后OnAfterRenderAsync - : 资源清理
Dispose
Best Practices
最佳实践
- Use for data loading
OnInitializedAsync - Check in
firstRenderOnAfterRenderAsync - Dispose subscriptions and timers
- Avoid long-running synchronous code
- 使用加载数据
OnInitializedAsync - 在中检查
OnAfterRenderAsyncfirstRender - 清理订阅和计时器
- 避免长时间运行的同步代码
Data Binding
数据绑定
One-Way Binding
单向绑定
razor
<p>@message</p>
<input value="@inputValue" />razor
<p>@message</p>
<input value="@inputValue" />Two-Way Binding
双向绑定
razor
<input @bind="inputValue" />
<input @bind="inputValue" @bind:event="oninput" />razor
<input @bind="inputValue" />
<input @bind="inputValue" @bind:event="oninput" />Event Handling
事件处理
razor
<button @onclick="HandleClick">Click</button>
<button @onclick="() => HandleClickWithParam(id)">Click</button>
<button @onclick="HandleClickAsync">Async Click</button>razor
<button @onclick="HandleClick">点击</button>
<button @onclick="() => HandleClickWithParam(id)">点击</button>
<button @onclick="HandleClickAsync">异步点击</button>Render Optimization
渲染优化
Prevent Unnecessary Renders
避免不必要的渲染
- Use for list items
@key - Implement when appropriate
ShouldRender() - Use judiciously
StateHasChanged() - Avoid inline handlers in loops
- 为列表项使用
@key - 适时实现
ShouldRender() - 谨慎调用
StateHasChanged() - 避免在循环中使用内联处理器
Virtualization
虚拟化
razor
<Virtualize Items="@items" Context="item">
<ItemContent>
<div>@item.Name</div>
</ItemContent>
</Virtualize>razor
<Virtualize Items="@items" Context="item">
<ItemContent>
<div>@item.Name</div>
</ItemContent>
</Virtualize>State Management
状态管理
Component State
组件状态
- Use private fields for component state
- Call when state changes externally
StateHasChanged() - Use for thread-safe updates
InvokeAsync
- 使用私有字段存储组件状态
- 当状态外部变更时调用
StateHasChanged() - 使用进行线程安全更新
InvokeAsync
Cascading Parameters
级联参数
razor
<CascadingValue Value="@currentTheme">
<ChildComponent />
</CascadingValue>
<!-- In child component -->
[CascadingParameter]
public Theme CurrentTheme { get; set; }razor
<CascadingValue Value="@currentTheme">
<ChildComponent />
</CascadingValue>
<!-- 在子组件中 -->
[CascadingParameter]
public Theme CurrentTheme { get; set; }State Containers
状态容器
- Create injectable state services
- Use events for state change notifications
- Consider Fluxor for complex state management
- 创建可注入的状态服务
- 使用事件通知状态变更
- 复杂状态管理可考虑Fluxor
Blazor Server vs WebAssembly
Blazor Server vs WebAssembly
Blazor Server
Blazor Server
- State lives on server
- Real-time connection via SignalR
- Faster initial load
- Requires stable connection
- Better for internal apps
- 状态存储在服务器端
- 通过SignalR实现实时连接
- 初始加载速度更快
- 需要稳定的网络连接
- 更适合内部应用
Blazor WebAssembly
Blazor WebAssembly
- Runs entirely in browser
- Larger initial download
- Works offline (PWA capable)
- No server resources per user
- Better for public apps
- 完全在浏览器中运行
- 初始下载包更大
- 支持离线运行(可实现PWA)
- 无需为每个用户占用服务器资源
- 更适合公共应用
API Integration
API集成
HTTP Client
HTTP客户端
csharp
@inject HttpClient Http
private async Task LoadData()
{
users = await Http.GetFromJsonAsync<List<User>>("api/users");
}csharp
@inject HttpClient Http
private async Task LoadData()
{
users = await Http.GetFromJsonAsync<List<User>>("api/users");
}Error Handling
错误处理
csharp
try
{
users = await Http.GetFromJsonAsync<List<User>>("api/users");
}
catch (HttpRequestException ex)
{
errorMessage = "Failed to load users";
}csharp
try
{
users = await Http.GetFromJsonAsync<List<User>>("api/users");
}
catch (HttpRequestException ex)
{
errorMessage = "加载用户失败";
}Error Handling
错误处理
Error Boundaries
错误边界
razor
<ErrorBoundary>
<ChildContent>
<RiskyComponent />
</ChildContent>
<ErrorContent Context="ex">
<p>An error occurred: @ex.Message</p>
</ErrorContent>
</ErrorBoundary>razor
<ErrorBoundary>
<ChildContent>
<RiskyComponent />
</ChildContent>
<ErrorContent Context="ex">
<p>发生错误:@ex.Message</p>
</ErrorContent>
</ErrorBoundary>Global Error Handling
全局错误处理
- Implement for custom handling
IErrorBoundary - Log errors to server
- Show user-friendly messages
- 实现进行自定义处理
IErrorBoundary - 将错误日志上传至服务器
- 显示用户友好的提示信息
Testing
测试
bUnit Testing
bUnit测试
csharp
[Fact]
public void ComponentRendersCorrectly()
{
using var ctx = new TestContext();
var cut = ctx.RenderComponent<Counter>();
cut.Find("p").MarkupMatches("<p>Current count: 0</p>");
cut.Find("button").Click();
cut.Find("p").MarkupMatches("<p>Current count: 1</p>");
}csharp
[Fact]
public void ComponentRendersCorrectly()
{
using var ctx = new TestContext();
var cut = ctx.RenderComponent<Counter>();
cut.Find("p").MarkupMatches("<p>Current count: 0</p>");
cut.Find("button").Click();
cut.Find("p").MarkupMatches("<p>Current count: 1</p>");
}Authentication
身份验证
Setup
配置
- Use
AuthenticationStateProvider - Use for conditional UI
AuthorizeView - Use attribute on pages
[Authorize] - Implement custom auth state provider for JWT
- 使用
AuthenticationStateProvider - 使用实现条件UI
AuthorizeView - 在页面上使用特性
[Authorize] - 为JWT实现自定义身份验证状态提供器
AuthorizeView
AuthorizeView
razor
<AuthorizeView>
<Authorized>
<p>Welcome, @context.User.Identity?.Name!</p>
</Authorized>
<NotAuthorized>
<p>Please log in.</p>
</NotAuthorized>
</AuthorizeView>razor
<AuthorizeView>
<Authorized>
<p>欢迎,@context.User.Identity?.Name!</p>
</Authorized>
<NotAuthorized>
<p>请登录。</p>
</NotAuthorized>
</AuthorizeView>Performance Tips
性能优化技巧
- Use for dynamic lists
@key - Implement virtualization for large lists
- Lazy load components with
@if - Minimize JavaScript interop calls
- Use streaming rendering in .NET 8+
- 为动态列表使用
@key - 为大型列表实现虚拟化
- 使用懒加载组件
@if - 减少JavaScript互操作调用
- 在.NET 8+中使用流式渲染