‹ 首页

abp-ui

@burakdmir · 收录于 昨天 · 上游提交 2 周前

ABP Framework v10.x (10.4/10.5) UI: MVC/Razor Pages (AbpPageModel), Blazor (AbpComponentBase), Angular, React (--modern), theming (LeptonX), menu contributor, dynamic proxy. Use when developing frontend, UI, pages, or components in ABP.

适合你,如果使用 ABP 框架时需要高效创建和管理前端 UI。

/ 通过 npx 安装 校验哈希
npx oh-my-skill add burakdmir/abp-skills/abp-ui
/ 通过 bash 安装
curl -fsSL https://oh-my-skill.com/install.sh | bash -s -- burakdmir/abp-skills/abp-ui
/ 已经装过?验证本机副本,不用重装
npx oh-my-skill verify burakdmir/abp-skills/abp-ui
安装目标可用 --agent / --scope 或 --to 明确指定;省略时只会在唯一已存在的 agent 目录上自动选择,零命中或多命中会停止并提示。content_hash 缺失或不一致均拒装。
13GitHub stars
~1.6K上下文体积 · 单文件
索引托管

怎么用

商店整理自技能原文 · 版本 ce71259 · 表述以原文为准
它做什么

Claude 在回答 ABP 框架 UI 问题时,能提供 MVC/Razor Pages、Blazor、Angular、React 的代码示例,以及主题、权限、菜单贡献等功能的实现指导。

什么时候触发

当用户提到“ABP UI”、“ABP MVC”、“ABP 前端”等关键词,或要求开发 ABP 框架的界面时触发。

装好后可以这样说
Claude 会返回 Blazor 组件代码。
Claude 会给出 AbpPageModel 示例。
Claude 会展示 tenantKey 设置。
技能原文 SKILL.md作者撰写 · MIT · ce71259

ABP Framework — UI & Frontend

ABP Framework v10.x (10.4/10.5) UI framework integrations. MVC/Razor Pages, Blazor, Angular, React, and UI theming.

Trigger
  • "ABP UI"
  • "ABP MVC"
  • "ABP Blazor"
  • "ABP Angular"
  • "ABP React"
  • "ABP theme"
  • "ABP Razor Pages"
  • "ABP frontend"
UI Framework Options

| Framework | Type | Note | |---|---|---| | MVC/Razor Pages | Server-side | Default, most mature | | Blazor Web App | Server-side (.NET 10) | Modern Blazor | | Blazor WASM | Client-side | SPA style | | Blazor Server | Server-side | With SignalR | | Angular | Client-side | TypeScript SPA | | React | Client-side | With the modern template | | MAUI Blazor | Cross-platform mobile | Team+ license |


MVC / Razor Pages
Module Registration
[DependsOn(typeof(AbpAspNetCoreMvcModule))]
public class MyWebModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.AddRazorPages();
    }
    
    public override void OnApplicationInitialization(ApplicationInitializationContext context)
    {
        var app = context.GetApplicationBuilder();
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthentication();
        app.UseAuthorization();
        app.UseConfiguredEndpoints(endpoints => endpoints.MapRazorPages());
    }
}
ABP Controller
[Area("App")]
[Route("api/app/book")]
public class BookController : AbpController
{
    private readonly IBookAppService _bookAppService;
    
    public BookController(IBookAppService bookAppService)
    {
        _bookAppService = bookAppService;
    }
    
    [HttpGet]
    public Task<PagedResultDto<BookDto>> GetListAsync(PagedAndSortedResultRequestDto input)
    {
        return _bookAppService.GetListAsync(input);
    }
}
Razor Page
public class IndexModel : AbpPageModel
{
    private readonly IBookAppService _bookAppService;
    
    public List<BookDto> Books { get; set; }
    
    public IndexModel(IBookAppService bookAppService)
    {
        _bookAppService = bookAppService;
    }
    
    public async Task OnGetAsync()
    {
        var result = await _bookAppService.GetListAsync(new PagedAndSortedResultRequestDto());
        Books = result.Items;
    }
}

Blazor
Blazor Web App Module
[DependsOn(
    typeof(AbpAspNetCoreComponentsWebAssemblyModule),
    typeof(AbpAutoMapperModule)
)]
public class MyBlazorModule : AbpModule { }
Blazor Component
@page "/books"
@inject IBookAppService BookAppService

<h3>Books</h3>

@if (books == null)
{
    <p>Loading...</p>
}
else
{
    <table class="table">
        <thead>
            <tr><th>Name</th><th>Type</th><th>Price</th></tr>
        </thead>
        <tbody>
            @foreach (var book in books.Items)
            {
                <tr>
                    <td>@book.Name</td>
                    <td>@book.Type</td>
                    <td>@book.Price</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private PagedResultDto<BookDto> books;

    protected override async Task OnInitializedAsync()
    {
        books = await BookAppService.GetListAsync(new PagedAndSortedResultRequestDto());
    }
}
Blazor Service Proxy
// The dynamic C# HTTP proxy is generated automatically
// Defined in the HttpApi.Client project

Angular
Service Proxy
abp generate-proxy -t ng

The automatically generated services are created in the src/app/proxy/ directory.

Using a Component
import { BookService } from '@proxy/books';

@Component({...})
export class BookListComponent {
  books: BookDto[] = [];
  
  constructor(private bookService: BookService) {}
  
  ngOnInit(): void {
    this.bookService.getList({}).subscribe(result => {
      this.books = result.items;
    });
  }
}
Multi-Tenancy (Angular)
// app.config.ts
export const appConfig: ApplicationConfig = {
  providers: [
    provideAbpCore(
      withOptions({
        tenantKey: "__tenant",  // Default
      })
    ),
  ],
};

React (Modern Template)

A React SPA is created with the modern template:

abp new Acme.BookStore --template app --modern
Project Structure
Acme.BookStore/
├── react/                    # React SPA (user interface)
├── src/
│   └── ...                   # Backend projects

In the microservice template:

Acme.BookStore/
├── apps/react/               # React SPA
├── apps/react-admin-console/ # Admin Console (served by the backend)
├── apps/auth-server/         # OpenIddict Auth Server
├── gateways/web/             # YARP reverse proxy
└── gateways/mobile/          # Mobile gateway
OpenIddict Client Seeding

The modern template seeds automatically:

  • MyProjectName_App — React SPA
  • MyProjectName_AdminConsole — Admin Console
shadcn/ui Theme
abp new Acme.BookStore --modern --shadcn-theme blue

Theme values: slate, pink, blue, turquoise, orange, purple


UI Theming

With the ABP UI theming system, you can use pre-built themes or custom themes.

Pre-built Themes

| Theme | Description | License | |---|---|---| | leptonx | LeptonX (full) | Team+ | | leptonx-lite | LeptonX Lite | Free | | basic | Basic Theme | Free |

Theme Selection
abp new Acme.BookStore --theme leptonx-lite
abp new Acme.BookStore --theme basic
Basic Theme Installation (MVC)
[DependsOn(
    typeof(AbpAspNetCoreMvcUiBasicThemeModule)
)]
public class MyWebModule : AbpModule { }

Authorization UI
Defining Permissions
public static class BookStorePermissions
{
    public const string GroupName = "BookStore";
    
    public const string Books = GroupName + ".Books";
    public const string BooksCreate = Books + ".Create";
    public const string BooksUpdate = Books + ".Update";
    public const string BooksDelete = Books + ".Delete";
}
Permission Provider
public class BookStorePermissionDefinitionProvider : PermissionDefinitionProvider
{
    public override void Define(IPermissionDefinitionContext context)
    {
        var bookStoreGroup = context.AddGroup(BookStorePermissions.GroupName);
        
        var booksPermission = bookStoreGroup.AddPermission(BookStorePermissions.Books);
        booksPermission.AddChild(BookStorePermissions.BooksCreate);
        booksPermission.AddChild(BookStorePermissions.BooksUpdate);
        booksPermission.AddChild(BookStorePermissions.BooksDelete);
    }
}
Checking Permissions in the UI
@* MVC/Razor *@
@if (await AuthorizationService.IsGrantedAsync(BookStorePermissions.BooksCreate))
{
    <button>Create Book</button>
}
@* Blazor *@
<Authorize Policy="BookStore.Books.Create">
    <button>Create Book</button>
</Authorize>

Menu Contribution
public class BookStoreMenuContributor : IMenuContributor
{
    public async Task ConfigureMenuAsync(MenuConfigurationContext context)
    {
        if (context.Menu.Name == StandardMenus.Main)
        {
            await ConfigureMainMenuAsync(context);
        }
    }

    private Task ConfigureMainMenuAsync(MenuConfigurationContext context)
    {
        context.Menu.AddItem(
            new ApplicationMenuItem(
                "BookStore",
                l["Menu:BookStore"],
                icon: "fa fa-book"
            ).AddItem(
                new ApplicationMenuItem(
                    "BookStore.Books",
                    l["Menu:Books"],
                    url: "/Books"
                )
            )
        );
        return Task.CompletedTask;
    }
}

Best Practices
  1. MVC/Razor Pages as the default choice — The most mature and best integrated
  2. Prefer Blazor Web App (.NET 10) — Instead of Blazor Server/WASM
  3. Use the modern template for React — With the --modern flag
  4. Use the dynamic C# proxy — Avoid writing an HTTP client manually
  5. Define permissions in a constant class — Don't use string literals
  6. Use the menu contributor — Add menu items in a modular way
  7. Start with LeptonX-Lite — Free, with sufficient features

What's New in v10.5
  • Blazorise upgraded to 2.2.1 (v10.5+). Align direct Blazorise package pins with ABP's version and re-test custom Blazor components after upgrading.
  • CMS Kit editor: CodeMirror updated to 6.0.2 (@abp/codemirror). If you customized CMS Kit editor resources, re-test the editor pages.
Related
  • [API](../abp-api/SKILL.md) — dynamic proxy, Auto API Controllers
  • [Authorization](../abp-authorization/SKILL.md) — checking permissions in the UI
  • [Localization](../abp-localization/SKILL.md) — UI texts, L[] helper
  • [Framework Core](../abp-framework/SKILL.md) — solution template UI options
  • ABP Docs: https://abp.io/docs/latest/framework/ui
按 MIT 许可原样转载,未经改动 · 在 GitHub 查看 →

评论

登录即可评论;带「已验证安装」的,是发布者名下有本店的安装或持有记录。