Blazor 学习笔记 - 查缺补漏_查缺补漏怎么用
myzbx 2025-09-09 07:25 2 浏览
1. 简介
Blazor 是 Microsoft 推出的开源框架,用于使用 C# 和 .NET 构建交互式 Web 应用程序,减少对 JavaScript 的依赖。
核心特性
- o 使用 C# 编写前端和后端逻辑,统一开发体验。
- o 组件化开发,支持代码复用。
- o 支持两种托管模型:Blazor Server 和 Blazor WebAssembly。
- o 与 ASP.NET Core 深度集成,支持 SignalR、依赖注入等。
- o 支持 AOT(Ahead-of-Time)编译以提升 WebAssembly 性能。
最新动态(截至 2025 年)
- o Blazor 在 .NET 8 和 .NET 9 中持续优化,支持混合模式(Blazor Hybrid)用于桌面和移动端开发(如 MAUI)。
- o 新增特性:增强的 SSR(服务器端渲染)支持、改进的组件生命周期管理。
2. 托管模型
特性Blazor ServerBlazor WebAssembly首次加载速度快慢(需下载运行时)是否依赖网络是否适用场景内部系统、实时协作单页应用、离线应用
Blazor Server
- o 运行方式:应用程序在服务器上运行,通过 SignalR 实时更新客户端 UI。
- o 优点:
- o 初始加载快
- o 可直接访问数据库、文件系统
- o 兼容性好
- o 缺点:
- o 依赖网络连接
- o 服务器负载较高
- o 适用场景:企业内部系统、聊天、仪表板。
Blazor WebAssembly
- o 运行方式:应用程序编译为 WebAssembly,在客户端浏览器运行。
- o 优点:
- o 完全在客户端运行,支持离线
- o 部署简单,适合 CDN
- o 借助 AOT 编译,性能接近原生
- o 缺点:
- o 首次加载较慢(约 2-5MB)
- o 浏览器需支持 WebAssembly
- o 适用场景:SPA、跨平台 Web 应用、离线应用。
Blazor Hybrid
- o 运行方式:结合 Blazor 和 .NET MAUI,用于开发桌面和移动端应用。
- o 特点:本地运行,复用 Blazor 组件,适合跨平台开发。
- o 适用场景:需要原生体验的应用。
3. 项目结构
- o Pages 文件夹:页面组件(.razor),通过 @page 定义路由。
- o Components 文件夹:可复用组件。
- o wwwroot 文件夹:静态资源(CSS、JS、图片等)。
- o Program.cs:入口点,配置服务。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorComponents(); // 注册 Blazor 组件服务
var app = builder.Build();
app.UseRouting();
app.MapRazorComponents<App>().AddInteractiveServerRenderMode(); // 渲染模式
app.Run();
- o App.razor:根组件,管理路由。
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="typeof(MainLayout)" />
</Found>
<NotFound>
<p>Sorry, page not found!</p>
</NotFound>
</Router>
- o MainLayout.razor:定义布局。
- o Shared 文件夹:共享组件(如导航栏)。
4. 组件开发
基本结构
@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
StateHasChanged(); // 手动刷新 UI
}
}
关键点
- o @page 定义路由。
- o @code 包含 C# 逻辑。
- o @ 用于绑定数据或事件。
5. 数据绑定
单向绑定
<p>Message: @message</p>
@code {
private string message = "Hello, Blazor!";
}
双向绑定
<input @bind="inputValue" />
<p>You typed: @inputValue</p>
@code {
private string inputValue = "";
}
表单验证
<EditForm Model="@user" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<InputText @bind-Value="user.Name" />
<ValidationMessage For="@(() => user.Name)" />
<button type="submit">Submit</button>
</EditForm>
@code {
private User user = new();
private void HandleValidSubmit() => Console.WriteLine(#34;Submitted: {user.Name}");
public class User {
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
}
}
6. 路由
@page "/user/{Id:int}"
<p>User ID: @Id</p>
@code {
[Parameter]
public int Id { get; set; }
}
导航
@inject NavigationManager Navigation
<button @onclick="NavigateToAbout">Go to About</button>
@code {
private void NavigateToAbout() => Navigation.NavigateTo("/about?query=example");
}
路由约束
@page "/product/{ProductId:guid}"
7. 依赖注入
@inject HttpClient Http
@inject IJSRuntime JS
@inject NavigationManager Navigation
@code {
protected override async Task OnInitializedAsync() {
var data = await Http.GetStringAsync("https://api.example.com/data");
}
}
自定义服务
- 1. 定义接口和服务:
public interface IMyService {
string GetData();
}
public class MyService : IMyService {
public string GetData() => "Hello from service!";
}
- 2. 注册服务(Program.cs):
builder.Services.AddSingleton<IMyService, MyService>();
- 3. 使用服务:
@inject IMyService MyService
<p>@MyService.GetData()</p>
8. 生命周期方法
@code {
protected override async Task OnInitializedAsync() {
// 初始化数据
}
protected override void OnParametersSet() {
// 参数变化时执行
}
protected override void OnAfterRender(bool firstRender) {
if (firstRender) {
// 首次渲染后操作
}
}
protected override bool ShouldRender() {
return isDataChanged;
}
}
9. 调用 JavaScript
C# 调用 JS
@inject IJSRuntime JS
<button @onclick="ShowAlert">Show Alert</button>
@code {
private async Task ShowAlert() => await JS.InvokeVoidAsync("alert", "Hello from Blazor!");
}
JS 调用 C#
[JSInvokable]
public static Task<string> GetMessage() => Task.FromResult("Hello from C#!");
async function callDotNet() {
const result = await DotNet.invokeMethodAsync('MyAssembly', 'GetMessage');
console.log(result);
}
10. 状态管理
public class AppState {
public int Counter { get; set; }
public event Action OnChange;
public void IncrementCounter() {
Counter++;
OnChange?.Invoke();
}
}
注册服务并使用:
builder.Services.AddSingleton<AppState>();
@inject AppState State
<p>Counter: @State.Counter</p>
@code {
protected override void OnInitialized() {
State.OnChange += StateHasChanged;
}
}
11. CSS 和样式
隔离 CSS
/* MyComponent.razor.css */
h3 {
color: blue;
}
全局 CSS
<link href="css/site.css" rel="stylesheet" />
内联样式
<div style="color: red;">Red text</div>
12. 性能优化
- o 使用 ShouldRender 控制是否重新渲染。
- o 避免在循环中创建大量组件实例。
- o 懒加载组件:
@if (isLoaded) {
<HeavyComponent />
}
- o AOT 编译(WebAssembly):
<PropertyGroup>
<RunAotCompilation>true</RunAotCompilation>
</PropertyGroup>
Blazor 新特性(.NET 8/9)
- o 静态服务器端渲染 (SSR):
<Routes @rendermode="RenderMode.Static" />
- o 新增 InputFile 组件:
<InputFile OnChange="@HandleFileUpload" />
@code {
private async Task HandleFileUpload(InputFileChangeEventArgs e) {
var file = e.File;
// 处理文件
}
}
- o 流式渲染:逐步加载页面内容,提升用户体验。
资源
- o 官方文档
- o GitHub 仓库
相关推荐
- 前端工程师养成计划 专区_前端工程师技能要求
-
前端工程师必修课本课程从最基本的概念开始讲起,步步深入,带领大家学习HTML、CSS样式基础知识,了解各种常用标签的意义以及基本用法,后半部分讲解CSS样式代码添加,为后面的案例课程打下基础。本课程让...
- 深入浅出虚拟 DOM 和 Diff 算法,及 Vue2 与 Vue3 中的区别
-
因为Diff算法,计算的就是虚拟DOM的差异,所以先铺垫一点点虚拟DOM,了解一下其结构,再来一层层揭开Diff算法的面纱,深入浅出,助你彻底弄懂Diff算法原理认识虚拟DOM虚拟...
- css 布局简述_css布局的几种方式
-
本篇简单介绍了css布局体系。包括Flowlayout、display、floats、positionFlowlayout(NormalFlow)CSSFormattingContext...
- dart系列之:HTML的专属领域,除了javascript之外,dart也可以
-
简介虽然dart可以同时用作客户端和服务器端,但是基本上dart还是用做flutter开发的基本语言而使用的。除了andorid和ios之外,web就是最常见和通用的平台了,dart也提供了对HTML...
- 原来隐藏一个DOM元素可以有这么多种方式,最后一种你肯定不知道
-
我们在日常编码的时候,隐藏一个dom元素有很多种方式,今天我们来盘点一下隐藏dom元素有哪些方式,最后一种,你绝对没有用过。display:none作为经常用来隐藏元素的css属性,di...
- JavaScript精通到深入_javascript进阶书籍推荐
-
前几天教大家从入门到精通,当然仅靠那一篇文章是不足以带领大家精通JavaScript的,今天给大家带来第二讲!BOM和DOM简介BOM,BrowserObjectModel,浏览器对象模型。BO...
- 巧克力:从一朵花开始的华丽变身_巧克力花束教程视频
-
世界上几乎所有的巧克力产品,都出自四五家大公司大型工厂里的流水线。然而,“手工制作巧克力”正在成为一种潮流,吸引着越来越多的人沉醉其中。这些娇嫩的花朵,是你吃过的每一块巧克力的开始。可可花直接生长在...
- browser-use:AI 驱动的浏览器自动化神器——DOM识别与交互详解
-
browser-use可以识别网页中可交互DOM内容,并能与之进行交互。本文将详细介绍browser-use实现这一核心功能的技术细节。一、可交互元素识别browser-use是通过DOMS...
- HTML DOM Progress 对象_html中的对象
-
Progress对象Progress对象是HTML5新增的。Progress对象表示一个HTML<progress>元素。<progress>元素表示任务...
- HTML DOM Script 对象_html document对象
-
Script对象Script对象表示一个HTML<script>元素。访问Script对象您可以使用getElementById()来访问<scrip...
- 虚拟DOM真的比操作原生DOM快吗?前端大神提供4个参考观点!收藏
-
尤雨溪:https://www.zhihu.com/question/31809713/answer/53544875VirtualDOM真的比操作原生DOM快吗?1.原生DOM操作v...
- 前沿|一种新的植入药物或可将HIV的预防时间持续一年
-
国外已经批准了一种叫做Truvada(中文名:特鲁瓦达)的药物用于HIV感染的暴露前预防。但是由于该药需要每天服用,因此有些人可能无法坚持,从而使得该药的预防效果降低。最近一项新的研究或许可以改变这种...
- 轻量级埋点sdk搭建,便捷更全面_埋点工具
-
引言借助埋点监控sdk,我们可以统计用户的点击,页面pv、uv,脚本错误、dom上报等关键信息等。一:项目初始化1.技术栈Tsrollup打包工具2.搭建项目npminit-ytsc--in...
- China's Humanoid Robotics Race Heats Up as Tesla's Optimus Hits a Wall
-
TMTPOST--Tesla'sonce-hypedhumanoidrobotproject,Optimus,hashitasnag.Partsprocurementhas...
- 单机训练速度提升640倍!独家解读快手商业广告模型GPU训练平台Persia
-
【导读】:近期,快手宣布将在2020年春节前实现3亿DAU,快手商业化营收步伐也随之加速。快手从2018年“商业化元年”开始推行个性化的广告推荐。截止5月底,快手DAU已经突破2亿。随着用户和使用时长...
- 一周热门
- 最近发表
-
- 前端工程师养成计划 专区_前端工程师技能要求
- 深入浅出虚拟 DOM 和 Diff 算法,及 Vue2 与 Vue3 中的区别
- css 布局简述_css布局的几种方式
- dart系列之:HTML的专属领域,除了javascript之外,dart也可以
- 原来隐藏一个DOM元素可以有这么多种方式,最后一种你肯定不知道
- JavaScript精通到深入_javascript进阶书籍推荐
- 巧克力:从一朵花开始的华丽变身_巧克力花束教程视频
- browser-use:AI 驱动的浏览器自动化神器——DOM识别与交互详解
- HTML DOM Progress 对象_html中的对象
- HTML DOM Script 对象_html document对象
- 标签列表
-
- HTML 简介 (30)
- HTML 响应式设计 (31)
- HTML URL 编码 (32)
- HTML Web 服务器 (31)
- HTML 表单属性 (32)
- HTML 音频 (31)
- HTML5 支持 (33)
- HTML API (36)
- HTML 总结 (32)
- HTML 全局属性 (32)
- HTML 事件 (31)
- HTML 画布 (32)
- HTTP 方法 (30)
- 键盘快捷键 (30)
- CSS 语法 (35)
- CSS 轮廓宽度 (31)
- CSS 谷歌字体 (33)
- CSS 链接 (31)
- CSS 定位 (31)
- CSS 图片库 (32)
- CSS 图像精灵 (31)
- SVG 文本 (32)
- 时钟启动 (33)
- HTML 游戏 (34)
- JS Loop For (32)