Blazor 从零开始:第1章 — 什么是 Blazor?
欢迎来到从零开始学 Blazor的第1章。如果你错过了介绍本系列目的和受众的介绍文章,请先阅读那篇——很短。
在这一章中,我们将回答一个根本性的问题:Blazor 是什么? 这听起来很简单,但答案有几个层面——尤其是因为多年来"Blazor"已经有了略微不同的含义。读完这篇文章,你将了解 Blazor 是什么、它如何融入 .NET 生态系统、有哪些不同的渲染模型,以及为什么你可能会选择它而不是 JavaScript 框架——或者不会。
简短的历史
Blazor 大约在 2017 年作为 Microsoft 的 Steve Sanderson 的实验性项目开始。这个想法很大胆:使用 WebAssembly 在浏览器中运行 C#,完全消除对 JavaScript 的需求。这是一个概念验证,名称是 Blazer 和 Razor 的刻意融合——Razor 是 Blazor 最终将在其上构建的模板引擎。
这个实验产生了足够的热情,让 Microsoft 认真对待。Blazor 于 2019 年 9 月作为 ASP.NET Core 3.0 的一部分发布,最初是 Blazor Server——一种在服务器上运行 C# 代码并使用实时 SignalR 连接将 UI 更新推送到浏览器的模型。Blazor WebAssembly 作为 ASP.NET Core 3.1 的一部分于 2020 年 5 月推出,为框架带来了真正的客户端执行。
.NET 6 和 7 改善了开发者体验。然后,2023 年 11 月发布的 .NET 8 从根本上重新思考了渲染模型,使用 Microsoft 称之为全栈 Web UI 的方式。静态服务器端渲染、流式渲染、交互式服务器、交互式 WebAssembly 和新的 Auto 模式都在一个项目的同一屋檐下共存。.NET 9 在此基础上构建并消除了粗糙之处。
这就是我们今天所处的位置。
Blazor 究竟是什么
从本质上说,Blazor 是一个面向 .NET 的基于组件的 UI 框架。你使用组件构建 UI——可以保存状态、响应事件并组合成更大结构的 C# 和 HTML 标记的自包含单元。如果你使用过 React 或 Vue,这个思维模型会感觉熟悉。关键区别在于,你写的是 C# 而不是 JavaScript。
Blazor 中的组件写在 .razor 文件中。.razor 文件使用 Razor 语法混合 HTML 标记和 C# 代码,你可能已经从 ASP.NET MVC 视图中了解过这种语法。一个简单的组件看起来像这样:
@page "/counter"
<h1>计数器</h1>
<p>当前计数: @currentCount</p>
<button @onclick="IncrementCount">点击我</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
没有 JavaScript。@onclick 指令将按钮点击绑定到 C# 方法。@currentCount 表达式渲染当前值。当状态改变时,Blazor 会确定需要更新 DOM 中的哪些内容。
这就是核心。其他所有内容——路由、依赖注入、表单、HTTP 调用——都建立在这个组件模型之上。
渲染模型
这里存在很多混淆,所以让我们精确一些。今天的"Blazor"指的是一系列渲染模式,而不是单一的部署模型。理解差异很重要,因为它影响性能、基础设施要求以及你的组件可以和不能做什么。
静态 SSR
最简单的模式。你的 Razor 组件在服务器上渲染为 HTML,该 HTML 被发送到浏览器。默认情况下没有持久连接、没有 WebAssembly、没有客户端交互性。这本质上是 Razor Pages 所做的,但使用组件模型。
用于内容丰富的页面、着陆页、任何不需要实时交互性的内容。
交互式服务器
组件代码在服务器上运行。浏览器和服务器之间建立 SignalR WebSocket 连接。当你点击按钮或在输入框中键入时,事件通过 WebSocket 传输到服务器,C# 代码执行,计算差异,然后 DOM 更新被发送回浏览器。
优势: 完全访问服务器资源(数据库、文件系统、密钥)。快速初始加载。下载量小。在不支持 WebAssembly 的浏览器中工作。
劣势: 每次用户交互都需要服务器往返,增加延迟。服务器资源随活跃连接数扩展。连接断开时应用会降级。
用于业务线应用、内部工具、服务器端数据访问比离线功能更重要的应用。
交互式 WebAssembly
.NET 运行时下载到浏览器,你的应用完全在客户端运行。初始下载后,应用完全离线工作,每次交互都是即时的——没有 UI 逻辑的服务器往返。
优势: 真正的客户端执行。离线工作。应用加载后服务器负载降低。
劣势: 更大的初始下载量(.NET 运行时 + 你的应用)。更慢的首次加载。需要 API 来访问服务器端数据。
用于具有离线功能的应用、需要即时响应性的工具、UI 不需要服务器处理的场景。
Auto 模式
在 .NET 8 中引入。应用以交互式服务器模式启动(快速初始加载,无需等待 WebAssembly 下载)。一旦 WebAssembly 文件在后台下载完成,后续访问会自动切换到 WebAssembly 模式。
这给你提供了服务器模式的快速首次加载,以及最终 WebAssembly 的完整客户端执行。这是最复杂的理解模型,但对许多应用来说是实用的默认值。
在同一应用中混合模式
在 .NET 8 及更高版本中,你不受限于整个应用的单一渲染模式。营销着陆页可以是静态 SSR;已验证的仪表板可以是交互式服务器;数据可视化小部件可以是交互式 WebAssembly。框架处理过渡。
在本系列中,我们将从交互式服务器开始,因为它最容易启动,具有最直接的思维模型。我们将在进行过程中探索其他模式。
Blazor 与 JavaScript 框架的比较
如果你使用过 React、Angular 或 Vue 进行开发,这可能是你好奇的比较。
相似之处是真实的。 Blazor 的组件模型刻意类似于 React。你有 props(Blazor 中的参数)、本地状态(@code 块中的字段)、生命周期钩子,以及相同的单向数据流/事件向上的通信模式。如果你了解 React,几小时内就会感到得心应手。
关键区别是语言。 在 Blazor 中你写 C#。业务逻辑、验证规则和数据模型都可以在 Blazor 前端和 ASP.NET Core 后端之间共享。当你已经用 C# 写好 User 类时,不再需要在 TypeScript 中重复。
生态系统差距是真实的,但正在缩小。 npm 生态系统庞大。UI 组件的 NuGet 生态系统较小,但已经大幅增长。对于特定的图表库或拖放小部件,JavaScript 仍然有更多选择。但对于大多数业务线应用,.NET 世界中可用的内容已经绰绰有余。
JavaScript 互操作在需要时存在。 Blazor 允许你从 C# 调用 JavaScript,从 JavaScript 调用 C#。对于没有 .NET 包装器的浏览器 API,或者当你想使用现有 JS 库时,互操作是可用的。它增加了一层,但并不痛苦。
诚实的答案: 如果你的团队完全是 JavaScript 开发者,正在构建一个 SEO、性能和 npm 生态系统至关重要的公开产品,请坚持使用 JavaScript。如果你的团队是 .NET 开发者,如果你正在构建内部或业务线应用,或者如果前后端之间的代码共享对你很重要,Blazor 是一个令人信服的选择。
跟进所需的内容
本系列其余部分你需要:
- .NET 9 SDK — 从 dot.net 下载
- IDE — Visual Studio 2022(社区版免费)、带有 C# Dev Kit 扩展的 VS Code,或 JetBrains Rider
- 基本的 C# 知识——类、属性、接口、async/await
就这些。不需要 Node、npm 或 webpack。
下一篇
在第2章中,我们将搭建你的第一个 Blazor 应用,浏览项目结构,并确保你能在本地运行它。最后你将拥有一个工作中的应用和对每个文件作用的清晰认识。
在那里见。