c#、.net、Fluent UI Blazor

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相似

相关推荐
iccb10134 小时前
5年,一个程序员是如何把私有化在线客服系统做到第一名的
前端·后端·github
假如让我当三天老蒯4 小时前
回归基本功:Map/Set 与 WeakMap/WeakSet 的区别
前端·面试
IT乐手4 小时前
48队都装不下你|国足第24次让全世界失望
前端
SoaringHeart5 小时前
Flutter最佳实践:IM聊天文字链接自动识别跳转
前端·flutter
掘金一周6 小时前
企业中要做智能体,最佳的方案是什么? | 沸点周刊 6.18
前端·人工智能·ai编程
Darling噜啦啦6 小时前
CSS 3D 变换与 Flex 布局实战:从零打造旋转立方体
前端·css
秃头网友小李6 小时前
前端难点:keep-alive 缓存什么?RouterView 的 key 为什么要带 scopeId?
前端·vue.js
鱼人6 小时前
CSS 变量:一个变量救你一百次复制粘贴
前端
长大19886 小时前
CSS 到底是什么?和 HTML 的区别一次讲清楚
前端
禅思院6 小时前
路由性能优化终极指南:从懒加载漏洞到边缘渲染的架构跃迁
前端·架构·前端框架