百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Blazor 学习笔记 - 查缺补漏_查缺补漏怎么用

myzbx 2025-09-09 07:25 2 浏览

1. 简介

Blazor 是 Microsoft 推出的开源框架,用于使用 C# 和 .NET 构建交互式 Web 应用程序,减少对 JavaScript 的依赖。

核心特性

  • o 使用 C# 编写前端和后端逻辑,统一开发体验。
  • o 组件化开发,支持代码复用。
  • o 支持两种托管模型:Blazor ServerBlazor 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. 1. 定义接口和服务:
public interface IMyService {
    string GetData();
}

public class MyService : IMyService {
    public string GetData() => "Hello from service!";
}
  1. 2. 注册服务(Program.cs):
builder.Services.AddSingleton<IMyService, MyService>();
  1. 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&#39;s Humanoid Robotics Race Heats Up as Tesla&#39;s Optimus Hits a Wall

TMTPOST--Tesla'sonce-hypedhumanoidrobotproject,Optimus,hashitasnag.Partsprocurementhas...

单机训练速度提升640倍!独家解读快手商业广告模型GPU训练平台Persia

【导读】:近期,快手宣布将在2020年春节前实现3亿DAU,快手商业化营收步伐也随之加速。快手从2018年“商业化元年”开始推行个性化的广告推荐。截止5月底,快手DAU已经突破2亿。随着用户和使用时长...