实现简单的`Blazor`低代码

本篇博客只实现基本的低代码,比如新增组件,动态修改组件参数

创建项目

首先创建一个空的Blazor Server,并且命名LowCode.Web

实现我们还需要引用一个Blazor组件库,由于作者用Masa Blazor比较多所以使用Masa Blazor

安装Masa Blazor

Masa Blazor添加到项目依赖中


    


修改Program.cs文件 增加了builder.Services.AddMasaBlazor();

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddMasaBlazor();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

打开_Imports.razor 添加以下代码

@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.JSInterop
@using LowCode.Web
@using Masa.Blazor
@using BlazorComponent
@using LowCode.Web.Components

修改Pages_Host.cshtml,添加以下代码

@page "/"
@using Microsoft.AspNetCore.Components.Web
@namespace LowCode.Web.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

    
    
    

    

    
    



An error has occurred. This application may no longer respond until reloaded. An unhandled exception has occurred. See browser dev tools for details. Reload 🗙

修改MainLayout.razor文件

@inherits LayoutComponentBase


    @Body

这样就完成安装了Masa Blazor

然后开始写实现

实现低代码组件设计

创建Components文件夹

创建渲染组件ComponentRender.razor,添加以下代码

@using LowCode.Web.Components.Options
@RenderFragment

@code{
    /// 
    /// 渲染组件
    /// 
    [Parameter]
    public RenderFragment RenderFragment { get; set; }

    /// 
    /// 渲染配置
    /// 
    public GenerateMButtonOptions GenerateMButtonOptions { get; set; }

    /// 
    /// 渲染动态代码
    /// 
    public string Code { get; set; }
}

定义组件库模板 DynamicComponentGenerator.razor,由于cs文件不能razor模板,所以创建razor文件,添加以下代码,以下代码我们添加三个组件模板,

@using LowCode.Web.Components.Options

@code {
    public static (RenderFragment, string) GenerateMButton(GenerateMButtonOptions options)
    {
        // 定义模板默认数据
        RenderFragment template = @@options.childContent;

        // 模板定义代码 (存在问题)
        var data = $@"{@options.childContent}";

        return (builder => { builder.AddContent(0, template); }, data);
    }

    public static (RenderFragment, string) GenerateMCard(GenerateMButtonOptions options)
    {
        RenderFragment template = @@options.childContent;

        var data = $@"{@options.childContent}";

        return (builder => { builder.AddContent(0, template); }, data);
    }

    public static (RenderFragment, string) GenerateMAvatar(GenerateMButtonOptions options)
    {
        RenderFragment template = @@options.childContent;

        var data = $@"{@options.childContent}";

        return (builder => { builder.AddContent(0, template); }, data);
    }
}

添加ComponentComponentType.cs 组件枚举

namespace LowCode.Web.Components;

public enum ComponentType
{
    MButton,

    MCart,

    MAvatar
}

添加ComponentComponentLibrary.razor用于显示支持的组件

mdi-card 按钮 mdi-id-card 卡片 mdi-id-card 头像

@code{

public delegate void OnClickDelegate(ComponentType type);

[Parameter]
public OnClickDelegate? OnClick { get; set; }

}


新增ComponentOptionsGenerateMButtonOptions.cs 添加以下代码 ,添加组件时的参数

using BlazorComponent;
using Microsoft.AspNetCore.Components;

namespace LowCode.Web.Components.Options;

public class GenerateMButtonOptions
{
    public string? height { get; set; }

    public string? width { get; set; }

    public bool block { get; set; }

    public bool dark { get; set; }

    public string Style { get; set; } = string.Empty;
    public string Class { get; set; } = string.Empty;

    public Dictionary? attributes { get; set; } = new();

    public RenderFragment? childContent { get; set; }
}

然后修改PagesIndex.razor

@page "/"
@using LowCode.Web.Components.Options


    
        

            

        
        
        
        
            @foreach (var item in Renders)
            {
                 Id = item.Key">
                    @item.Value.RenderFragment
                
            }
        
    
    
        
            
                @*TODO:通过反射实现获取组件参数根据参数类型显示指定组件动态修改参数*@
                @foreach (var item in Renders)
                {
                    var options = item.Value.GenerateMButtonOptions;
                    if (item.Key == Id)
                    {
                        
                        
                        
                        
                        
                        新增扩展参数输入框
                        @foreach (var e in options.attributes)
                        {
                            
                            
                        }
                        删除
                    }
                }
            
        
    


@code {
    public string Id { get; set; }
    private Dictionary Renders = new();

    private RenderFragment RenderFragment { get; set; }

    private void AddOptionsAttribute(Dictionary attribute)
    {
        attribute.Add("new","");
    }

    private void DeleteComponent(string key)
    {
        Renders.Remove(key);
    }

    private void CreateOnClick(ComponentType type)
    {
        GenerateMButtonOptions options = null;
        string code;
        switch (type)
        {
            case ComponentType.MButton:
                options = new()
                {
                    childContent = @新建的按钮,
                    attributes = new Dictionary(),
                    width = "100px",
                };

                (RenderFragment, code) = DynamicComponentGenerator.GenerateMButton(options);

                Renders.Add(Guid.NewGuid().ToString("N"), new Render() { RenderFragment = RenderFragment, GenerateMButtonOptions = options, Code = code });

                break;
            case ComponentType.MCart:

                options = new()
                {
                    childContent = @多个按钮,
                    attributes = new Dictionary(),
                    width = "100px",
                };

                (RenderFragment, code) = DynamicComponentGenerator.GenerateMCard(options);

                Renders.Add(Guid.NewGuid().ToString("N"), new Render() { RenderFragment = RenderFragment, GenerateMButtonOptions = options, Code = code });
                break;
            case ComponentType.MAvatar:
                options = new()
                {
                    childContent = @,
                    attributes = new Dictionary(),
                    width = "100px",
                };

                (RenderFragment, code) = DynamicComponentGenerator.GenerateMAvatar(options);

                Renders.Add(Guid.NewGuid().ToString("N"), new Render() { RenderFragment = RenderFragment, GenerateMButtonOptions = options, Code = code });
                break;
            default:
                throw new ArgumentOutOfRangeException(nameof(type), type, null);
        }

        StateHasChanged();
    }
}

这样就实现了整个简单的低代码操作,我们可以使用看看效果,简单了解实现原理

我们定义了组件的模板,这个模板是固定的,通过Blazor提供的双向绑定实现动态修改组件参数,这种方式可能不太适合完整的低代码,但是也是不错的思路,

实现简单的`Blazor`低代码插图

这个项目还处于Demo阶段,不知道是否有大佬一块研究,研究技术极限,Blazor非常好用,推荐

GitHub
项目是MIT开源,希望大佬一块学习,促进Blazor生态

来着Token的分享

文章来源于互联网:实现简单的Blazor低代码

THE END
分享
二维码