646

前端项目

概述

  • 项目前端类库,包含配置、路由、页面,基于Castle动态代理访问后端WebApi
  • 如果采用Server模式,可以移除Castle动态代理。
  • 项目SDK默认为Microsoft.NET.Sdk.BlazorWebAssembly,如果不采用Auto模式,可以改成Microsoft.NET.Sdk.Razor
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
        <StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>
    </PropertyGroup>
    <!--引用包,如果不采用Auto模式,可以删除前5个包-->
    <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.8" />
        <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.8" />
        <PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
        <PackageReference Include="Castle.Core" Version="5.1.1" />
        <PackageReference Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
        <PackageReference Include="Known.AntBlazor" Version="1.0.10" />
        <ProjectReference Include="..\Sample\Sample.csproj" />
    </ItemGroup>
</Project>

页面组件

  • 页面组件通常为Razor文件,如果不熟悉Razor,可以参考微软官网文档
  • 项目模板默认提供安装、登录和首页,可以根据需求自定义。
  • 移动端页面放在Apps文件夹中。
  • 电脑端页面放在Pages文件夹中,各模块再细分子文件夹。
  • 简单页面表单可在线设计,复杂表单可自定义开发Razor文件。
  • 模块列表页面继承BaseTablePage<T>类。

注意: 前端按钮方法名称与 actions.txt 中定义的按钮 ID 一致。 Toolbar 按钮方法无参数、表格操作列方法需要有一个参数(表格行数据对象)。

// 表格列表页面组件
[Route("/bds/tests")]
public class TestList : BaseTablePage<TbTest>
{
    private ITestService Service;

    // 初始化页面组件
    protected override async Task OnPageInitAsync()
    {
        await base.OnPageInitAsync();
        Service = await CreateServiceAsync<ITestService>(); // 创建服务实例
        //Table.FormType = typeof(RoleForm); // 如果是自定义表单,这样设置即可
        Table.OnQuery = Service.QueryTestsAsync; // 设置查询方法
    }

    // 新增,Toolbar 无参方法
    public void New() => Table.NewForm(Service.SaveTestAsync, new TbTest());
    // 批量删除,Toolbar 无参方法
    public void DeleteM() => Table.DeleteM(Service.DeleteTestsAsync);
    // 编辑,操作列有参方法
    public void Edit(TbTest row) => Table.EditForm(Service.SaveTestAsync, row);
    // 删除,操作列有参方法
    public void Delete(TbTest row) => Table.Delete(Service.DeleteTestsAsync, row);
    // 导入,Toolbar 无参方法
    public async void Import() => await ShowImportAsync();
    // 导出,Toolbar 无参方法
    public async void Export() => await ExportDataAsync();
}

路由组件

  • Blazor程序全局路由。
<KContext Value="context">
    <Router AppAssembly="typeof(AppClient).Assembly" AdditionalAssemblies="Config.Assemblies">
        <Found Context="routeData">
            <KRouteData Value="routeData">
                <RouteView RouteData="routeData" DefaultLayout="typeof(AntLayout)" />
            </KRouteData>
        </Found>
        <NotFound>
            <Result Status="404" />
        </NotFound>
    </Router>
    <AntContainer /> /*AntDesign提示框容器*/
    <AntReconnector /> /*断连或更新提示UI*/
</KContext>

@code {
    private UIContext context;

    [Parameter] public string IPAddress { get; set; }
    [Parameter] public bool IsMobile { get; set; }

    protected override void OnInitialized()
    {
        context = new UIContext();
        context.IPAddress = IPAddress;
        context.IsMobile = IsMobile;
        base.OnInitialized();
    }
}

配置类

  • 配置项目前端组件。
public static class AppClient
{
    // WebApi请求动态代理生成器(如果采用Server模式,可以删除)
    private static readonly ProxyGenerator Generator = new();

    // 添加项目前端页面组件
    public static void AddSampleRazor(this IServiceCollection services)
    {
        // 添加框架AntDesign组件库
        services.AddKnownAntDesign(); 
        // 添加项目前端程序集
        Config.AddModule(typeof(AppClient).Assembly);
        // 设置系统错误码及描述
        UIConfig.Errors["403"] = new ErrorConfigInfo { Description = "你没有此页面的访问权限。" };
    }

    // 添加项目前端所需配置,如HttpClient和动态代理(如果采用Server模式,可以删除)
    internal static void AddSampleClient(this IServiceCollection services)
    {
        services.AddHttpClient();
        services.AddAuthorizationCore();
        services.AddCascadingAuthenticationState();
        services.AddScoped<IAuthStateProvider, AuthStateProvider>();
        services.AddScoped<AuthenticationStateProvider, AuthStateProvider>();
        services.AddKnownClient(info =>
        {
            info.InterceptorType = type => typeof(HttpClientInterceptor<>).MakeGenericType(type);
            info.InterceptorProvider = (type, interceptor) =>
            {
                return Generator.CreateInterfaceProxyWithoutTarget(type, ((IAsyncInterceptor)interceptor).ToInterceptor());
            };
        });
        services.AddSampleRazor();
    }
}