项目

本文档有多个版本。请选择最适合您的选项。

UI

Blazor UI:主题系统

简介

ABP提供了一个完整的UI主题系统,其目标如下:

  • 可重用的 应用程序模块独立于主题开发的,因此它们可以与任何UI主题配合使用。
  • UI主题由最终的应用程序决定
  • 主题通过NuGet包分发,因此易于升级
  • 最终应用程序可以自定义所选主题。

为了实现这些目标,ABP:

  • 确定了一套所有主题都使用和适配的基础库。因此,模块和应用程序开发者可以依赖并使用这些库,而无需依赖于特定主题。
  • 提供了一个由所有主题实现的布局部件系统(如导航菜单工具栏)。因此,模块和应用程序可以贡献到布局中,从而构成一个一致的应用程序UI。

当前提供的主题

目前,官方提供了三个主题:

概述

基础库

所有主题都必须依赖于Volo.Abp.AspNetCore.Components.WebAssembly.Theming NuGet包,因此它们间接依赖于以下库:

  • Twitter Bootstrap 作为基础的HTML/CSS框架。
  • Blazorise 作为组件库,支持Bootstrap并添加了额外的组件,如数据网格和树。
  • FontAwesome 作为基础的CSS字体库。
  • Flag Icon 作为显示国家旗帜的库。

这些库被选为基础库,可供应用程序和模块使用。

由于Blazorise库已经以原生方式为Bootstrap组件提供了必要的功能,因此不使用Bootstrap的JavaScript部分。

布局

所有主题都必须为应用程序定义一个布局。下图显示了基础主题应用程序布局中的用户管理页面:

basic-theme-application-layout-blazor

同一页面在Lepton主题应用程序布局中的显示如下:

lepton-theme-application-layout

如您所见,页面相同,但上述主题中的外观完全不同。

应用程序布局通常包括以下部分:

实现主题

主题本质上是一个Razor类库。

最简单的方法

创建新主题的最简单方法是添加基础主题源代码模块及其源代码,然后进行自定义。

abp add-package Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme --with-source-code --add-to-solution-file

全局样式/脚本

主题通常需要向页面添加全局样式。ABP提供了一个系统来管理全局样式和脚本。主题可以实现IBundleContributor接口,以向页面添加全局样式或脚本文件。

示例:向页面添加样式

using Volo.Abp.Bundling;

namespace MyTheme
{
    public class MyThemeBundleContributor : BundleContributor
    {
        public override void ConfigureBundle(BundleConfigurationContext context)
        {
            context.Files.AddIfNotContains("_content/MyTheme/styles.css");
        }
    }
}
[DependsOn(
    typeof(AbpAspNetCoreComponentsWebAssemblyThemingBundlingModule)
)]
public class MyBlazorWebAssemblyBundlingModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        Configure<AbpBundlingOptions>(options =>
        {
            // 添加样式捆绑包
            options.StyleBundles.Get(BlazorWebAssemblyStandardBundles.Styles.Global)
                .AddContributors(typeof(MyThemeBundleContributor));
        });
    }
}

在此示例中,styles.css文件应添加到主题项目的wwwroot文件夹中。

有关更多信息,请参阅全局样式和脚本文档。

布局部件

典型的布局由多个部件组成。主题应在每个布局中包含必要的部件。

示例:基础主题的应用程序布局包含以下部件

basic-theme-application-layout-parts

应用程序代码和模块只能在页面内容部分显示内容。如果它们需要更改其他部分(例如添加菜单项、添加工具栏项、更改品牌标识区域中的应用程序名称等),则应使用ABP的API。

以下部分解释了ABP预定义的基本部件,这些部件可以由主题实现。

将布局拆分为组件/部分是一个良好的实践,这样最终应用程序可以根据需要部分覆盖它们以实现自定义。

品牌标识

应使用IBrandingProvider服务来获取应用程序的名称和徽标URL,以便在品牌标识部分渲染。

应用程序启动模板 实现了此接口,以便应用程序开发者设置这些值。

主菜单

IMenuManager服务用于获取主菜单项并在布局上渲染。

示例:获取主菜单以在Razor组件中渲染

// Razor组件的代码后置文件
public partial class NavMenu
{
    private readonly IMenuManager _menuManager;

    public NavMenu(IMenuManager menuManager)
    {
        _menuManager = menuManager;
    }
    
    protected override async Task OnInitializedAsync()
    {
        var menu = await _menuManager.GetAsync(StandardMenus.Main);
        //...
    }
}

有关导航系统的更多信息,请参阅导航/菜单文档。

主工具栏

IToolbarManager服务用于获取主工具栏项并在布局上渲染。此工具栏的每个项都是一个Razor组件,因此可以包含任何类型的UI元素。注入IToolbarManager并使用GetAsync获取工具栏项:

var toolbar = await _toolbarManager.GetAsync(StandardToolbars.Main);

有关工具栏系统的更多信息,请参阅工具栏文档。

主题有责任向主工具栏添加两个预定义项:语言选择和用户菜单。为此,创建一个实现IToolbarContributor接口的类,并将其添加到AbpToolbarOptions中,如下所示:

Configure<AbpToolbarOptions>(options =>
{
    options.Contributors.Add(new BasicThemeMainTopToolbarContributor());
});
语言选择

语言选择工具栏项通常是一个下拉菜单,用于在语言之间切换。使用ILanguageProvider获取可用语言列表,并使用CultureInfo.CurrentUICulture了解当前语言。

使用本地存储通过Abp.SelectedLanguage键获取和设置当前语言。

示例:获取当前选择的语言

var selectedLanguageName = await JsRuntime.InvokeAsync<string>(
    "localStorage.getItem",
    "Abp.SelectedLanguage"
    );

示例:设置选择的语言

await JsRuntime.InvokeVoidAsync(
    "localStorage.setItem",
    "Abp.SelectedLanguage",
    "en-US"
    );

更改语言后,主题应重新加载页面:

await JsRuntime.InvokeVoidAsync("location.reload");
用户菜单

用户菜单包含与用户帐户相关的链接。像使用主菜单一样使用IMenuManager,但这次使用StandardMenus.User参数,如下所示:

var menu = await _menuManager.GetAsync(StandardMenus.User);

可以使用 ICurrentUserICurrentTenant 服务来获取当前用户和租户名称。

页面提示

IAlertManager服务用于获取当前页面提示并在布局上渲染。有关更多信息,请参阅页面提示文档。

在本文档中