1.启动项目
1.创建 Blazor WebAssembly 项目
dotnet new blazorserver -o FluentBlazorApp
创建的是 Blazor Server 应用,这是一种服务端渲染的应用,UI 更新通过 SignalR 连接与服务器进行通信。
dotnet new blazorwasm -n FluentBlazorApp
创建的是 Blazor WebAssembly 应用,这是一种客户端应用,代码直接在浏览器中运行。
2.添加 FluentUI Blazor 包
dotnet add package Microsoft.Fast.Components.FluentUI
3.配置服务 (修改 Program.cs)
js
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Fast.Components.FluentUI;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
// 添加 FluentUI 服务
builder.Services.AddFluentUIComponents(); // 👈 关键配置
// 添加 HttpClient(API 调用需要)
builder.Services.AddScoped(sp =>
new HttpClient {
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
});
await builder.Build().RunAsync();
4.添加静态资源引用
js
<!DOCTYPE html>
<html lang="en">
<head>
...
<!-- 添加 FluentUI 样式和脚本 -->
<link href="_content/Microsoft.Fast.Components.FluentUI/css/fast-components.min.css" rel="stylesheet" />
<script src="_content/Microsoft.Fast.Components.FluentUI/js/web-components.min.js"></script>
</head>
<body>
<div id="app">Loading...</div>
<div id="blazor-error-ui">An error has occurred.</div>
<script src="_framework/blazor.webassembly.js"></script>
</body>
</html>
5.添加命名空间引用
编辑 _Imports.razor
arduino
@using Microsoft.Fast.Components.FluentUI
6.创建主页面组件
创建 Pages/Home.razor
:
js
@page "/"
<FluentCard>
<h1>欢迎使用 FluentUI Blazor 客户端!</h1>
<FluentTextField @bind-Value="Username" Label="用户名" Placeholder="输入用户名" />
<FluentButton Appearance="Appearance.Primary"
@onclick="HandleLogin"
Class="mt-2">
登录
</FluentButton>
<div class="mt-3">
<FluentCheckbox @bind-Value="RememberMe">记住我</FluentCheckbox>
</div>
</FluentCard>
@code {
private string Username { get; set; } = "";
private bool RememberMe { get; set; } = false;
private void HandleLogin()
{
// 这里可以添加登录逻辑
Console.WriteLine($"登录: {Username}, 记住我: {RememberMe}");
}
}
7.配置导航菜单
编辑 Shared/MainLayout.razor
:
less
@inherits LayoutComponentBase
<FluentDesignSystemProvider>
<FluentDrawer @ref="drawerRef" Width="250px">
<FluentNavMenu>
<FluentNavLink Href="/" Match="NavLinkMatch.All">
<FluentIcon Value="@(new Icons.Regular.Size20.Home())" Slot="start" />
首页
</FluentNavLink>
<FluentNavLink Href="/dashboard">
<FluentIcon Value="@(new Icons.Regular.Size20.Dashboard())" Slot="start" />
仪表盘
</FluentNavLink>
<FluentNavLink Href="/settings">
<FluentIcon Value="@(new Icons.Regular.Size20.Settings())" Slot="start" />
设置
</FluentNavLink>
</FluentNavMenu>
</FluentDrawer>
<div class="main">
<FluentTopNav Title="FluentUI Blazor 客户端" @ref="topNav">
<FluentButton Appearance="Appearance.Lightweight"
Icon="@(new Icons.Regular.Size20.Menu())"
@onclick="ToggleDrawer" />
</FluentTopNav>
<div class="content px-4">
@Body
</div>
</div>
</FluentDesignSystemProvider>
@code {
private FluentDrawer? drawerRef;
private FluentTopNav? topNav;
private void ToggleDrawer() => drawerRef?.Toggle();
}
9.运行项目
arduino
dotnet run
项目结构说明 (客户端应用)
bash
FluentBlazorClient/
├── wwwroot/ # 静态资源
│ ├── index.html # 入口文件
│ └── css/ # 自定义CSS
├── Pages/ # 页面组件
│ ├── Home.razor
│ ├── Dashboard.razor
│ └── Settings.razor
├── Shared/ # 共享组件
│ ├── MainLayout.razor
│ └── NavMenu.razor
├── Program.cs # 入口和配置
└── _Imports.razor # 全局命名空间
API 调用示例
创建 Services/ApiService.cs
:
csharp
public class ApiService
{
private readonly HttpClient _http;
public ApiService(HttpClient http)
{
_http = http;
}
public async Task<List<TodoItem>> GetTodosAsync()
{
return await _http.GetFromJsonAsync<List<TodoItem>>("api/todos") ?? [];
}
}
public record TodoItem(int Id, string Title, bool IsCompleted);
在 Program.cs
注册服务:
ini
builder.Services.AddScoped<ApiService>();
在组件中使用:
ini
@inject ApiService ApiService
<FluentDataGrid Items="@_todos" TItem="TodoItem">
<PropertyColumn Title="ID" Property="@(t => t.Id)" />
<PropertyColumn Title="任务" Property="@(t => t.Title)" />
<TemplateColumn Title="状态">
<FluentCheckbox Checked="@(context.IsCompleted)" />
</TemplateColumn>
</FluentDataGrid>
@code {
private List<TodoItem> _todos = [];
protected override async Task OnInitializedAsync()
{
_todos = await ApiService.GetTodosAsync();
}
}
本地存储 (浏览器存储)
csharp
dotnet add package Blazored.LocalStorage
配置服务 (Program.cs):
js
using Blazored.LocalStorage;
builder.Services.AddBlazoredLocalStorage();
在组件中使用
less
@inject ILocalStorageService LocalStorage
@inject ISyncLocalStorageService SyncLocalStorage
<FluentButton @onclick="SavePrefs">保存偏好</FluentButton>
@code {
private UserPreferences _prefs = new();
protected override void OnInitialized()
{
// 同步获取
_prefs = SyncLocalStorage.GetItem<UserPreferences>("userPrefs") ?? new();
}
private async Task SavePrefs()
{
// 异步保存
await LocalStorage.SetItemAsync("userPrefs", _prefs);
}
class UserPreferences
{
public string Theme { get; set; } = "light";
public int PageSize { get; set; } = 10;
}
}
发布应用
r
dotnet publish -c Release
2.关键字
class
声明一个类
using
用来引入相关命名空间
int
整数运算符
public
这是一种访问修饰符 ,其作用是指定成员(像类、方法、字段等)的访问权限为 "公开"。使用public
修饰的成员,能够被同一程序集或者引用了该程序集的其他程序集里的任何代码访问。
js
public class Person {
public string Name; // 任何代码都能访问Name字段
public int Age; // 任何代码也都能访问Age字段
}
struct
此关键字用于定义结构体,结构体是一种值类型,一般用于封装小型相关变量组。和类相比,结构体的性能更高,适合存储简单的数据。
js
public struct Point {
public int X; // 结构体的字段
public int Y; // 结构体的字段
}
Point p = new Point { X = 10, Y = 20 }; // 创建结构体实例
void
无返回值
override
重写方法
class
与new相似