🚀 快速安装

复制以下命令并运行,立即安装此 Skill:

npx @anthropic-ai/skills install github/awesome-copilot/fluentui-blazor

💡 提示:需要 Node.js 和 NPM

Fluent UI Blazor — 使用者指南

本技能旨在教授如何在 Blazor 应用程序中正确使用 Microsoft.FluentUI.AspNetCore.Components(版本 4)NuGet 包。

关键规则

1. 无需手动添加 <script><link> 标签

该库通过 Blazor 的静态 Web 资产和 JS 初始化程序自动加载所有 CSS 和 JS。切勿告诉用户为核心库添加 <script><link> 标签。

2. 基于服务的组件必须添加提供者组件

这些提供者组件必须添加到根布局(例如 MainLayout.razor)中,其对应的服务才能正常工作。如果没有它们,服务调用将静默失败(无错误,无 UI)。

<FluentToastProvider />
<FluentDialogProvider />
<FluentMessageBarProvider />
<FluentTooltipProvider />
<FluentKeyCodeProvider />

3. 在 Program.cs 中注册服务

builder.Services.AddFluentUIComponents();

// 或者带配置:
builder.Services.AddFluentUIComponents(options =>
{
    options.UseTooltipServiceProvider = true;  // 默认值:true
    options.ServiceLifetime = ServiceLifetime.Scoped; // 默认值
});

服务生命周期规则:

  • ServiceLifetime.Scoped — 适用于 Blazor Server / Interactive(默认)
  • ServiceLifetime.Singleton — 适用于独立运行的 Blazor WebAssembly
  • ServiceLifetime.Transient会抛出 NotSupportedException

4. 图标需要单独的 NuGet 包

dotnet add package Microsoft.FluentUI.AspNetCore.Components.Icons

配合 @using 别名使用:

@using Icons = Microsoft.FluentUI.AspNetCore.Components.Icons

<FluentIcon Value="@(Icons.Regular.Size24.Save)" />
<FluentIcon Value="@(Icons.Filled.Size20.Delete)" Color="@Color.Error" />

模式:Icons.[变体].[尺寸].[名称]

  • 变体:Regular(常规)、Filled(填充)
  • 尺寸:Size12Size16Size20Size24Size28Size32Size48

自定义图像:Icon.FromImageUrl("/path/to/image.png")

切勿使用基于字符串的图标名称 — 图标是强类型类。

5. 列表组件的绑定模式

FluentSelect<TOption>FluentCombobox<TOption>FluentListbox<TOption>FluentAutocomplete<TOption>工作方式与 <InputSelect> 不同。它们使用:

  • Items — 数据源(IEnumerable<TOption>
  • OptionText — 用于提取显示文本的 Func<TOption, string?>
  • OptionValue — 用于提取值字符串的 Func<TOption, string?>
  • SelectedOption / SelectedOptionChanged — 用于单选绑定
  • SelectedOptions / SelectedOptionsChanged — 用于多选绑定
<FluentSelect Items="@countries"
              OptionText="@(c => c.Name)"
              OptionValue="@(c => c.Code)"
              @bind-SelectedOption="@selectedCountry"
              Label="Country" />

不能像这样使用(错误模式):

@* 错误 — 不要使用 InputSelect 模式 *@
<FluentSelect @bind-Value="@selectedValue">
    <option value="1">One</option>
</FluentSelect>

6. FluentAutocomplete 特性

  • 对于搜索输入文本,使用 ValueText(不是 Value — 它已过时)
  • OnOptionsSearch 是过滤选项所必需的回调
  • 默认为 Multiple=“true”
<FluentAutocomplete TOption="Person"
                    OnOptionsSearch="@OnSearch"
                    OptionText="@(p => p.FullName)"
                    @bind-SelectedOptions="@selectedPeople"
                    Label="搜索人员" /> <!-- 翻译 -->

@code {
    private void OnSearch(OptionsSearchEventArgs<Person> args)
    {
        args.Items = allPeople.Where(p =>
            p.FullName.Contains(args.Text, StringComparison.OrdinalIgnoreCase));
    }
}

7. 对话框服务模式

不要切换 <FluentDialog> 标签的可见性。正确的服务模式是:

  1. 创建一个实现 IDialogContentComponent<TData> 的内容组件:
public partial class EditPersonDialog : IDialogContentComponent<Person>
{
    [Parameter] public Person Content { get; set; } = default!;

    [CascadingParameter] public FluentDialog Dialog { get; set; } = default!;

    private async Task SaveAsync()
    {
        await Dialog.CloseAsync(Content);
    }

    private async Task CancelAsync()
    {
        await Dialog.CancelAsync();
    }
}
  1. 通过 IDialogService 显示对话框:
[Inject] private IDialogService DialogService { get; set; } = default!;

private async Task ShowEditDialog()
{
    var dialog = await DialogService.ShowDialogAsync<EditPersonDialog, Person>(
        person,
        new DialogParameters
        {
            Title = "编辑人员", // 翻译
            PrimaryAction = "保存", // 翻译
            SecondaryAction = "取消", // 翻译
            Width = "500px",
            PreventDismissOnOverlayClick = true,
        });

    var result = await dialog.Result;
    if (!result.Cancelled)
    {
        var updatedPerson = result.Data as Person;
    }
}

对于便捷对话框:

await DialogService.ShowConfirmationAsync("你确定吗?", "是", "否"); // 翻译
await DialogService.ShowSuccessAsync("完成!"); // 翻译
await DialogService.ShowErrorAsync("出错了。"); // 翻译

8. Toast 通知

[Inject] private IToastService ToastService { get; set; } = default!;

ToastService.ShowSuccess("项目保存成功"); // 翻译
ToastService.ShowError("保存失败"); // 翻译
ToastService.ShowWarning("请检查你的输入"); // 翻译
ToastService.ShowInfo("有新更新可用"); // 翻译

FluentToastProvider 参数:Position(默认 TopRight)、Timeout(默认 7000ms)、MaxToastCount(默认 4)。

9. 设计令牌和主题仅在渲染后生效

设计令牌依赖 JS 互操作。切勿在 OnInitialized 中设置它们 — 应使用 OnAfterRenderAsync

<FluentDesignTheme Mode="DesignThemeModes.System"
                   OfficeColor="OfficeColor.Teams"
                   StorageName="mytheme" />

10. FluentEditForm 与 EditForm

只有在 FluentWizard 的步骤内部(用于分步验证)才需要 FluentEditForm。对于常规表单,请使用标准的 EditForm 配合 Fluent 表单组件:

<EditForm Model="@model" OnValidSubmit="HandleSubmit">
    <DataAnnotationsValidator />
    <FluentTextField @bind-Value="@model.Name" Label="姓名" Required /> <!-- 翻译 -->
    <FluentSelect Items="@options"
                  OptionText="@(o => o.Label)"
                  @bind-SelectedOption="@model.Category"
                  Label="类别" /> <!-- 翻译 -->
    <FluentValidationSummary />
    <FluentButton Type="ButtonType.Submit" Appearance="Appearance.Accent">保存</FluentButton> <!-- 翻译 -->
</EditForm>

要获得 Fluent 样式,请使用 FluentValidationMessageFluentValidationSummary 替代标准的 Blazor 验证组件。

参考文件

有关特定主题的详细指南,请参阅:

📄 原始文档

完整文档(英文):

https://skills.sh/github/awesome-copilot/fluentui-blazor

💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。