:Blazor 全栈开发——告别 JavaScript 焦虑

📅 2026/7/11 5:11:13
:Blazor 全栈开发——告别 JavaScript 焦虑
专注于业务逻辑的后端同学来说简直是噩梦。微软也意识到了这个痛点于是 Blazor 诞生了。Blazor 的核心理念很简单用 C# 替代 JavaScript。你可以在 Razor 页面里写 C# 代码处理点击事件甚至直接操作 DOM虽然不推荐。这让 .NET 开发者拥有了无缝的全栈开发能力。二、Blazor Server实时交互的黑魔法Blazor 主要有两种托管模型新手最容易搞混刚子先帮你理一理Blazor WebAssembly (客户端)应用被编译成 WebAssembly直接在浏览器里运行。这就像 React 一样部署在静态服务器上不依赖服务器实时计算。Blazor Server (服务端)应用在服务器上运行通过 SignalR一种 WebSocket 技术与浏览器实时通信。刚子敲黑板 本教程选择 Blazor Server 作为入门。为什么调试简单你可以直接在 Visual Studio 里打断点断点会停在后端的 C# 代码上就像调试普通后台代码一样。加载快浏览器不需要下载整个 .NET 运行时首屏加载速度极快。适合后台管理系统非常适合企业内部使用的后台管理界面开发。三、动手实战创建第一个 Blazor 项目我们重新创建一个项目为了方便演示这次建立一个独立的 Blazor Server 项目。3.1 创建项目在终端执行dotnet new blazorserver -n MyTodoUIcd MyTodoUIdotnet run可视化界面创建项目 打开vs2022→点击创建新项目→选择Blazor Web 应用,点击下一步→依次输入项目名称、解决方案及项目文件路径点击下一步→选择.NET 8 点击创建即可点击创建新项目 选择Blazor Web 应用 依次输入项目名称、解决方案及项目文件路径 创建.NET 8项目启动后浏览器访问 https://localhost:xxxx你会看到一个漂亮的官方模板页面。Blazor Server 应用程序默认模板首页展示图。注意这里创建应用时要选择 Blazor Web 应用 而不是 Blazor Server 应用。从.NET 8开始经典的“Blazor Server”模板已被全新的“Blazor Web App”模板所取代这一点在微软的官方文档和技术社区中都有提及。新的模板统一了Blazor Server和Blazor WebAssembly的开发体验并引入了更灵活的“交互渲染模式”Interactive Render Modes因此VS不再直接提供名为“Blazor Server”的.NET 8项目选项。创建Blazor Server 应用不支持.NET 8。3.2 项目结构解析打开项目重点关注以下几个文件夹blazor web 应用 结构图Layout/存放公共布局组件如 MainLayout.razor布局模板和 NavMenu.razor导航菜单。Pages/存放 .razor 页面组件。比如 Home.razor 就是首页。_Imports.razor类似于 using 命名空间这里引入的命名空间会自动应用到所有 Razor 组件。四、组件化开发一切皆组件Blazor 的开发模式是组件化的。一个页面通常由多个小组件拼凑而成。4.1 创建一个简单的计数器组件打开 Pages/Home.razor把内容清空写入以下代码page “/”rendermode InteractiveServer欢迎来到刚子的计数器当前计数:currentCountbutton class“btn btn-primary” οnclick“IncrementCount”点击我 1code {// 这里写 C# 逻辑private int currentCount 0;private void IncrementCount() { currentCount; }}代码解析page “/”定义路由告诉 Blazor 这是首页。currentCount使用 符号将 C# 变量输出到 HTML 中。οnclick“IncrementCount”将 HTML 的点击事件绑定到 C# 的方法上。运行项目点击按钮你会发现数字变了而且完全不需要写 JavaScript也不用操作 DOMdocument.getElementById…Blazor 会自动帮你更新界面。五、实战进阶连接后端 API光有个计数器没意思我们要把之前教程里做好的 Todo API 接入进来。为了模拟真实的前后端分离场景我们假设后端 API 运行在 http://localhost:5000。快速新建一个极简的 ASP.NET Core Web API不需要手动写控制器直接用 最小 API 方式几行代码就搞定。步骤如下在现有解决方案中添加新项目右键解决方案 → 添加 → 新建项目选择 ASP.NET Core Web API项目名称TodoApi框架.NET 8不勾选“使用控制器” 这样会生成最小 API 模板修改 Program.cs 为以下代码var builder WebApplication.CreateBuilder(args);var app builder.Build();// 内存数据存储var todos new List{new Todo { Id 1, Title “学习 Blazor”, IsDone false },new Todo { Id 2, Title “测试 API”, IsDone true }};// GET /todosapp.MapGet(“/todos”, () todos);// DELETE /todos/{id}app.MapDelete(“/todos/{id}”, (int id) {var todo todos.FirstOrDefault(t t.Id id);if (todo null) return Results.NotFound();todos.Remove(todo);return Results.NoContent();});// POST /todosapp.MapPost(“/todos”, (Todo todo) {todo.Id todos.Max(t t.Id) 1;todos.Add(todo);return Results.Created($“/todos/{todo.Id}”, todo);});app.Run();public class Todo{public int Id { get; set; }public string? Title { get; set; }public bool IsDone { get; set; }}注意路由是 /todos复数没有 api 前缀。后面的前端调用也需要同步修改。5.1 注入 HttpClient在 Blazor Web App 中我们通过 HttpClient 发起网络请求。首先在 Program.cs 中注册服务// Program.cs// … 其他代码 …// 注册 HttpClientBaseAddress 设为后端 API 地址builder.Services.AddScoped(sp new HttpClient{BaseAddress new Uri(“http://localhost:5000”) // 这里替换为你实际的后端地址});// …5.2 定义数据模型为了接收 JSON 数据我们需要定义一个简单的 DTO 类。在项目中新建 Models/TodoItemDto.cspublic class TodoItemDto{public int Id { get; set; }public string? Title { get; set; }public bool IsDone { get; set; }}5.3 获取并展示数据新建一个页面 Pages/Todo.razorpage “/todo”rendermode InteractiveServerusing MyTodoUI.Modelsinject HttpClient Http待办事项列表if (todos null){正在加载数据…}else{foreach (var item in todos){}ID标题状态操作item.Iditem.Title(item.IsDone ? “已完成” : “进行中”)button class“btn btn-sm btn-danger” οnclick“() DeleteTodo(item.Id)”删除}code {private List? todos;// 组件初始化时触发适合加载数据 protected override async Task OnInitializedAsync() { try { // 调用 GET /todos 接口 todos await Http.GetFromJsonAsyncListTodoItemDto(todos); } catch (Exception ex) { Console.WriteLine($获取数据失败: {ex.Message}); } } private async Task DeleteTodo(int id) { // 调用 DELETE /todos/{id} 接口 await Http.DeleteAsync($todos/{id}); // 刷新列表 todos await Http.GetFromJsonAsyncListTodoItemDto(todos); }}Blazor 页面展示从后端 API 获取的待办事项列表数据截图刚子小贴士 注意到 inject HttpClient Http 了吗这依然是依赖注入。Blazor 的组件本质上也是一个类我们可以直接在视图中注入服务非常方便。另外 Blazor Web App务必在组件上添加 rendermode InteractiveServer 。OnInitializedAsync 是 Blazor 的生命周期方法相当于 React 的 useEffect 或 Vue 的 mounted在这里发起网络请求是最标准的做法。六、双向绑定让表单变简单Web 开发离不开表单。Blazor 提供了强大的双向绑定功能。6.1 添加新待办我们在 Todo.razor 底部添加一个输入框添加新任务code {// … 之前的代码 …private TodoItemDto newTodo new TodoItemDto() { };private async Task AddTodo() { // 调用 POST /todos 接口 var response await Http.PostAsJsonAsync(todos, newTodo); if (response.IsSuccessStatusCode) { newTodo new TodoItemDto(); // 清空输入框 todos await Http.GetFromJsonAsyncListTodoItemDto(todos); // 刷新列表 } }}核心解析bind“newTodo.Title”这是双向绑定的魔法。当你在输入框打字时newTodo.Title 会自动更新当你修改 newTodo 时输入框也会自动变。EditFormBlazor 提供的表单组件可以集成我们之前讲的 DataAnnotations 验证。刚子敲黑板 Blazor 的表单处理比原生 HTML 强大得多。你甚至可以在 InputText 上加 直接复用我们在第五篇写的验证规则前端连验证逻辑都不用写了七、延伸阅读刚子的 Blazor 深度系列本篇实战教程旨在帮你快速打通前后端。如果你在实战过程中想要更深入地了解 Blazor 的基础概念、路由机制、布局系统或 JS 交互强烈推荐阅读我之前整理的系列专栏那里有更细致的图文讲解Blazor 入门指南一简介与环境搭建Blazor 入门指南二组件与数据绑定Blazor 入门指南三布局与路由Blazor 入门指南四JavaScript 互操作