Blazor UI:导航 / 菜单
每个应用程序都有一个主菜单,允许用户导航到应用程序的页面/屏幕。某些应用程序可能在不同UI部分包含多个菜单。
ABP 是一个模块化应用开发框架。每个模块都可能需要向菜单添加项目。
因此,ABP提供了一个菜单基础架构,其中:
- 应用程序或模块可以向菜单添加项目,而无需知道菜单是如何渲染的。
- 主题能够正确地渲染菜单。
添加菜单项
为了添加菜单项(或操作现有项),您需要创建一个实现 IMenuContributor 接口的类。
应用程序启动模板 已经包含了一个
IMenuContributor的实现。因此,您可以在该类内部添加项目,而无需创建新类。
示例:添加一个包含 客户 和 订单 子菜单项的 CRM 菜单项
using System.Threading.Tasks;
using MyProject.Localization;
using Volo.Abp.UI.Navigation;
namespace MyProject.Web.Menus
{
public class MyProjectMenuContributor : IMenuContributor
{
public async Task ConfigureMenuAsync(MenuConfigurationContext context)
{
if (context.Menu.Name == StandardMenus.Main)
{
await ConfigureMainMenuAsync(context);
}
}
private async Task ConfigureMainMenuAsync(MenuConfigurationContext context)
{
var l = context.GetLocalizer<MyProjectResource>();
context.Menu.AddItem(
new ApplicationMenuItem("MyProject.Crm", l["Menu:CRM"])
.AddItem(new ApplicationMenuItem(
name: "MyProject.Crm.Customers",
displayName: l["Menu:Customers"],
url: "/crm/customers")
).AddItem(new ApplicationMenuItem(
name: "MyProject.Crm.Orders",
displayName: l["Menu:Orders"],
url: "/crm/orders")
)
);
}
}
}
- 此示例仅向主菜单(
StandardMenus.Main:参见下面的标准菜单部分)添加项目。 - 它从
context获取一个IStringLocalizer来本地化菜单项的显示名称。 - 将“客户”和“订单”添加为CRM菜单的子项。
创建菜单贡献者后,您需要将其添加到模块的 ConfigureServices 方法中的 AbpNavigationOptions:
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new MyProjectMenuContributor());
});
此示例使用了一些本地化键作为显示名称,这些键应在本地化文件中定义:
"Menu:CRM": "CRM",
"Menu:Orders": "订单",
"Menu:Customers": "客户"
有关本地化的更多信息,请参阅本地化文档。
运行应用程序时,您将看到添加到主菜单的菜单项:
菜单由当前UI主题渲染。因此,根据您的主题,主菜单的外观可能完全不同。
关于菜单贡献者,需要注意以下几点:
- ABP在需要渲染菜单时会调用
ConfigureMenuAsync方法。 - 每个菜单项都可以有子项。因此,您可以添加无限深度的菜单项(但是,您的UI主题可能不支持无限深度)。
- 通常,只有叶子菜单项才有
url。当您单击父菜单时,会打开或关闭其子菜单,您不会导航到父菜单项的url。 - 如果一个菜单项没有子项且未定义
url,则它不会在UI上渲染。这简化了菜单项的授权:您只需要授权子项(参见下一节)。如果没有任何子项被授权,则父项会自动消失。
菜单项属性
菜单项有更多选项(ApplicationMenuItem 类的构造函数)。以下是所有可用选项的列表:
name(string, 必需):菜单项的唯一名称。displayName(string, 必需):菜单项的显示名称/文本。您可以像之前所示那样本地化它。url(string):菜单项的URL。icon(string):图标名称。默认支持免费的 Font Awesome 图标类。例如:fa fa-book。只要您将必要的CSS文件包含到应用程序中,您可以使用任何CSS字体图标类。order(int):菜单项的顺序。默认值为1000。除非您指定顺序值,否则项目按添加顺序排序。customData(object):一个可以关联到菜单项并在渲染菜单项时使用的自定义对象。target(string):菜单项的目标。可以为null(默认)、"_blank"、"_" 或 Web 应用程序的框架名称。elementId(string):可用于渲染具有特定 HTMLid属性的元素。cssClass(string):菜单项的附加字符串类。groupName(string):可用于对菜单项进行分组。
授权
如上所示,菜单贡献者动态地贡献菜单。因此,您可以执行任何自定义逻辑或从任何源获取菜单项。
一个用例是授权。您通常希望通过检查权限来添加菜单项。
示例:检查当前用户是否拥有权限
if (await context.IsGrantedAsync("MyPermissionName"))
{
//...添加菜单项
}
您可以使用
context.AuthorizationService直接访问IAuthorizationService。
自定义组件
可以使用自定义组件来渲染菜单项,而不是使用主题的默认组件。Volo.Abp.UI.Navigation 命名空间中的 UseComponent 扩展方法可用于为菜单项设置自定义组件。
示例:为菜单项设置自定义组件
context.Menu.Items.Add(
new ApplicationMenuItem("MyProject.Crm.About", "关于", "/about")
.UseComponent<AboutMenuItemComponent>()
);
菜单项将渲染 _AboutMenuItemComponent.razor 组件。
解析依赖关系
可以使用 context.ServiceProvider 来解析任何服务依赖。
示例:获取服务
var myService = context.ServiceProvider.GetRequiredService<IMyService>();
//...使用服务
您无需关心释放/处置服务。ABP会处理它。
管理菜单
菜单中有一个由ABP添加的特殊菜单项:管理菜单。它通常由预构建的管理 应用程序模块 使用:
如果您想向管理菜单项下添加菜单项,可以使用 context.Menu.GetAdministration() 扩展方法:
context.Menu.GetAdministration().AddItem(...)
操作现有菜单项
ABP 按照模块依赖顺序执行菜单贡献者。因此,您可以操作您的应用程序或模块(直接或间接)所依赖的菜单项。
示例:为身份模块添加的 Users 菜单项设置图标
var userMenu = context.Menu.FindMenuItem(IdentityMenuNames.Users);
userMenu.Icon = "fa fa-users";
context.Menu使您能够访问所有先前菜单贡献者添加的菜单项。
菜单组
您可以定义组,并将菜单项与组关联。
示例:
using System.Threading.Tasks;
using MyProject.Localization;
using Volo.Abp.UI.Navigation;
namespace MyProject.Web.Menus
{
public class MyProjectMenuContributor : IMenuContributor
{
public async Task ConfigureMenuAsync(MenuConfigurationContext context)
{
if (context.Menu.Name == StandardMenus.Main)
{
await ConfigureMainMenuAsync(context);
}
}
private async Task ConfigureMainMenuAsync(MenuConfigurationContext context)
{
var l = context.GetLocalizer<MyProjectResource>();
context.Menu.AddGroup(
new ApplicationMenuGroup(
name: "Main",
displayName: l["Main"]
)
)
context.Menu.AddItem(
new ApplicationMenuItem("MyProject.Crm", l["Menu:CRM"], groupName: "Main")
.AddItem(new ApplicationMenuItem(
name: "MyProject.Crm.Customers",
displayName: l["Menu:Customers"],
url: "/crm/customers")
).AddItem(new ApplicationMenuItem(
name: "MyProject.Crm.Orders",
displayName: l["Menu:Orders"],
url: "/crm/orders")
)
);
}
}
}
UI主题将决定是否渲染组,如果决定渲染,渲染方式由主题决定。目前只有LeptonX主题实现了菜单组。
标准菜单
菜单是一个命名组件。一个应用程序可以包含多个具有不同唯一名称的菜单。有两个预定义的标准菜单:
Main:应用程序的主菜单。包含指向应用程序页面的链接。定义为常量:Volo.Abp.UI.Navigation.StandardMenus.Main。User:用户资料菜单。定义为常量:Volo.Abp.UI.Navigation.StandardMenus.User。
上面的内容已经涵盖了 Main 菜单。当用户登录时,User 菜单可用:
您可以通过检查 context.Menu.Name 来向 User 菜单添加项目,如下所示:
if (context.Menu.Name == StandardMenus.User)
{
//...添加项目
}
IMenuManager
IMenuManager 通常由 UI 主题 用于在 UI 上渲染菜单项。因此,通常不需要直接使用 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);
//...
}
}
抠丁客





