Enterprise-level component library based on Bootstrap and Blazor
gitee
version
license
download
repo
commit
build
coverage

Tree 树形控件

用清晰的层级结构展示信息,可展开或折叠

基础的树形结构展示

Demo

通过设置 OnTreeItemClick 属性监控树形控件节点被点击时的事件,点击树形控件节点时下面日志显示选中节点的数据

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

适用于需要选择层级时使用

Demo

通过设置 OnTreeItemChecked 属性监控树形控件节点被勾选时的事件,选中树形控件节点前复选框时下面日志显示选中节点的数据

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

适用于单选节点

Demo

通过设置 ShowRadio 属性节点前面显示 Radio 组件

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

可将 Tree 的某些节点设置为禁用状态

Demo

通过设置数据源 TreeItem 对象的 Disabled 属性,来控制此节点是否可以进行勾选动作,设置为 false 时不影响节点展开/收缩功能

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

对于同一级的节点,每次只能展开一个

Demo

通过设置 Tree 组件的 IsAccordion 属性开启手风琴效果

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

可将 Tree 的某些节点设置为默认展开或默认选中

Demo

通过设置 TreeItem 对象的 IsCollapsed 属性,来控制此节点是否默认为展开状态,本例中 导航二 默认为展开状态,其余节点默认为收缩状态

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

通过设置 ShowIcon 来控制组件是否显示图标

Demo

通过设置 TreeItem 对象的 ShowIcon 属性,来控制此节点是否显示图标

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

通过设置 ClickToggleNode 来控制点击节点时是否进行展开收缩操作

Demo

通过设置 TreeItem 对象的 ClickToggleNode 属性,来控制此节点是否通过点击来实现展开收缩操作

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

Tree 组件内部可开启 Checkbox 内置到验证表单时会显示 DisplayName 此功能在树状组件内需要禁止

Demo

通过设置 ShowCheckbox 属性显示 Checkbox 内置到验证组件 ValidateForm 中不显示 DisplayName

  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

展开节点时动态添加子节点

Demo

通过设置节点 HasChildNode 控制是否显示节点小箭头图片 。通过Tree的 OnExpandNode 委托添加节点

  • 导航一
  • 导航二
    • 子菜单一
    • 懒加载
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 懒加载延时
  • 导航三

通过设置 TreeItem Template 来实现自己的节点模板

Demo
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

通过设置 TreeItem CssClass 来实现自己的节点样式

Demo
  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

通过设置 OnTreeItemChecked 回调委托获取所有节点

Demo
  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

通过设置 ShowSkeleton 使异步加载数据时组件显示骨架屏

Demo
  • 导航一
  • 导航二
    • 子菜单一
    • 子菜单二
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • 子菜单三
  • 导航三

Attributes

Loading...

TreeItem 属性

Loading...
@page "/trees"

<h3>Tree 树形控件</h3>

<h4>用清晰的层级结构展示信息,可展开或折叠</h4>

<DemoBlock Title="基础用法" Introduction="基础的树形结构展示" Name="Normal">
    <p>
        通过设置 <code>OnTreeItemClick</code> 属性监控树形控件节点被点击时的事件,点击树形控件节点时下面日志显示选中节点的数据
    </p>
    <Tree Items="@Items" OnTreeItemClick="@OnTreeItemClick" />
    <BlockLogger @ref="Trace" class="mt-3" />
</DemoBlock>

<DemoBlock Title="多选框" Introduction="适用于需要选择层级时使用" Name="Checkbox">
    <p>
        通过设置 <code>OnTreeItemChecked</code> 属性监控树形控件节点被勾选时的事件,选中树形控件节点前复选框时下面日志显示选中节点的数据
    </p>
    <Tree Items="@CheckedItems" ShowCheckbox="true" OnTreeItemChecked="@OnTreeItemChecked" />
    <BlockLogger @ref="TraceChecked" class="mt-3" />
</DemoBlock>

<DemoBlock Title="单选框" Introduction="适用于单选节点" Name="ShowRadio">
    <p>
        通过设置 <code>ShowRadio</code> 属性节点前面显示 <code>Radio</code> 组件
    </p>
    <Tree Items="@CheckedItems" ShowRadio="true" />
</DemoBlock>

<DemoBlock Title="禁用状态" Introduction="可将 Tree 的某些节点设置为禁用状态" Name="TreeDisable">
    <p>
        通过设置数据源 <code>TreeItem</code> 对象的 <code>Disabled</code> 属性,来控制此节点是否可以进行勾选动作,设置为 <code>false</code> 时不影响节点展开/收缩功能
    </p>
    <Tree Items="@DisabledItems" ShowCheckbox="true" />
</DemoBlock>

<DemoBlock Title="手风琴模式" Introduction="对于同一级的节点,每次只能展开一个" Name="AccordionModel">
    <p>通过设置 <code>Tree</code> 组件的 <code>IsAccordion</code> 属性开启手风琴效果</p>
    <Tree Items="@Items" ShowCheckbox="true" IsAccordion="true" />
</DemoBlock>

<DemoBlock Title="默认展开和默认选中" Introduction="可将 <code>Tree</code> 的某些节点设置为默认展开或默认选中" Name="DefauleExpand">
    <p>
        通过设置 <code>TreeItem</code> 对象的 <code>IsCollapsed</code> 属性,来控制此节点是否默认为展开状态,本例中 <b>导航二</b> 默认为展开状态,其余节点默认为收缩状态
    </p>
    <Tree Items="@ExpandItems" ShowCheckbox="true" />
</DemoBlock>

<DemoBlock Title="显示图标" Introduction="通过设置 <code>ShowIcon</code> 来控制组件是否显示图标" Name="TreeDisplayIcon">
    <p>
        通过设置 <code>TreeItem</code> 对象的 <code>ShowIcon</code> 属性,来控制此节点是否显示图标
    </p>
    <Tree Items="@GetIconItems()" ShowIcon="true" ShowCheckbox="true" />
</DemoBlock>

<DemoBlock Title="点击节点展开收缩功能" Introduction="通过设置 <code>ClickToggleNode</code> 来控制点击节点时是否进行展开收缩操作" Name="TreeClickExpand">
    <p>
        通过设置 <code>TreeItem</code> 对象的 <code>ClickToggleNode</code> 属性,来控制此节点是否通过点击来实现展开收缩操作
    </p>
    <Tree Items="@Items" ShowIcon="true" ShowCheckbox="true" ClickToggleNode="true" />
</DemoBlock>

<DemoBlock Title="Tree 组件内置到验证表单中" Introduction="<code>Tree</code> 组件内部可开启 <code>Checkbox</code> 内置到验证表单时会显示 <code>DisplayName</code> 此功能在树状组件内需要禁止" Name="TreeValidationForm">
    <p>
        通过设置 <code>ShowCheckbox</code> 属性显示 <code>Checkbox</code> 内置到验证组件 <code>ValidateForm</code> 中不显示 <code>DisplayName</code>
    </p>
    <ValidateForm Model="@Model">
        <Tree Items="@Items" OnTreeItemClick="@OnTreeItemClick" ShowCheckbox="true" />
    </ValidateForm>
</DemoBlock>

<DemoBlock Title="懒加载" Introduction="展开节点时动态添加子节点" Name="TreeLazyLoading">
    <p>
        通过设置节点 <code>HasChildNode</code> 控制是否显示节点小箭头图片 。通过Tree的 <code>OnExpandNode</code> 委托添加节点
    </p>
    <Tree ClickToggleNode="true" Items="@GetLazyItems()" OnExpandNode="OnExpandNode" />
</DemoBlock>

<DemoBlock Title="自定义节点" Introduction="通过设置 <code>TreeItem</code> <code>Template</code> 来实现自己的节点模板" Name="TreeCustomNode">
    <Tree ClickToggleNode="true" Items="GetTemplateItems()" />
</DemoBlock>

<DemoBlock Title="节点颜色" Introduction="通过设置 <code>TreeItem</code> <code>CssClass</code> 来实现自己的节点样式" Name="TreeNodeColor">
    <Tree ClickToggleNode="true" Items="GetColorItems()" />
</DemoBlock>

<DemoBlock Title="获取所有选中节点" Introduction="通过设置 <code>OnTreeItemChecked</code> 回调委托获取所有节点" Name="CheckedItems">
    <Tree ShowCheckbox="true" Items="@Items" OnTreeItemChecked="@OnTreeItemChecked" />
    <BlockLogger @ref="TraceCheckedItems" class="mt-3" />
</DemoBlock>

<DemoBlock Title="加载骨架屏" Introduction="通过设置 <code>ShowSkeleton</code> 使异步加载数据时组件显示骨架屏" Name="ShowSkeleton">
    <Button Text="异步加载" IsAsync="true" Icon="fa fa-fa" OnClick="OnLoadAsyncItems" />
    <Tree Items="@AsyncItems" ShowSkeleton="true" class="mt-3" />
</DemoBlock>

<AttributeTable Items="@GetAttributes()" />

<AttributeTable Items="@GetTreeItemAttributes()" Title="TreeItem 属性" />
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

using BootstrapBlazor.Components;
using BootstrapBlazor.Shared.Common;
using BootstrapBlazor.Shared.Components;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.Localization;

namespace BootstrapBlazor.Shared.Samples;

/// <summary>
/// 
/// </summary>
public sealed partial class Trees
{
    [NotNull]
    private BlockLogger? Trace { get; set; }

    [NotNull]
    private BlockLogger? TraceChecked { get; set; }

    [NotNull]
    private BlockLogger? TraceCheckedItems { get; set; }

    [Inject]
    [NotNull]
    private IStringLocalizer<Foo>? Localizer { get; set; }

    private Foo Model => Foo.Generate(Localizer);

    private List<TreeItem> Items { get; set; } = TreeDataFoo.GetTreeItems();

    private List<TreeItem> CheckedItems { get; set; } = GetCheckedItems();

    private List<TreeItem> ExpandItems { get; set; } = GetExpandItems();

    private List<TreeItem>? AsyncItems { get; set; }

    /// <summary>
    /// OnInitializedAsync 方法
    /// </summary>
    /// <returns></returns>
    protected override async Task OnInitializedAsync()
    {
        await OnLoadAsyncItems();
    }

    private async Task OnLoadAsyncItems()
    {
        AsyncItems = null;
        await Task.Delay(2000);
        AsyncItems = TreeDataFoo.GetTreeItems();
    }

    private static List<TreeItem> GetCheckedItems()
    {
        var ret = TreeDataFoo.GetTreeItems();
        ret[1].Items[1].Checked = true;
        return ret;
    }

    private static List<TreeItem> GetExpandItems()
    {
        var ret = TreeDataFoo.GetTreeItems();
        ret[1].IsCollapsed = false;
        return ret;
    }

    private List<TreeItem> DisabledItems { get; set; } = GetDisabledItems();

    private static List<TreeItem> GetDisabledItems()
    {
        var ret = TreeDataFoo.GetTreeItems();
        ret[1].Items[1].IsDisabled = true;
        return ret;
    }

    private static List<TreeItem> GetIconItems() => TreeDataFoo.GetTreeItems();

    private static List<TreeItem> GetLazyItems()
    {
        var ret = TreeDataFoo.GetTreeItems();
        ret[1].Items[0].IsCollapsed = false;
        ret[1].Items[1].Text = "懒加载";
        ret[1].Items[1].HasChildNode = true;
        ret[1].Items[2].Text = "懒加载延时";
        ret[1].Items[2].HasChildNode = true;
        ret[1].Items[2].Key = "Delay";

        return ret;
    }

    private static List<TreeItem> GetTemplateItems()
    {
        var ret = TreeDataFoo.GetTreeItems();
        ret[0].Template = BootstrapDynamicComponent.CreateComponent<CustomerTreeItem>().Render();
        return ret;
    }

    private static List<TreeItem> GetColorItems()
    {
        var ret = TreeDataFoo.GetTreeItems();
        ret[0].CssClass = "text-primary";
        ret[1].CssClass = "text-success";
        ret[2].CssClass = "text-danger";
        return ret;
    }

    private class CustomerTreeItem : ComponentBase
    {
        [Inject]
        [NotNull]
        private ToastService? ToastService { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="builder"></param>
        protected override void BuildRenderTree(RenderTreeBuilder builder)
        {
            builder.OpenComponent<Button>(0);
            builder.AddAttribute(1, nameof(Button.Icon), "fa fa-fa");
            builder.AddAttribute(2, nameof(Button.Text), "Click");
            builder.AddAttribute(3, nameof(Button.OnClick), EventCallback.Factory.Create<MouseEventArgs>(this, e =>
            {
                ToastService.Warning("自定义 TreeItem", "测试 TreeItem 按钮点击事件");
            }));
            builder.CloseComponent();
        }
    }

    private Task OnTreeItemClick(TreeItem item)
    {
        Trace.Log($"TreeItem: {item.Text} clicked");
        return Task.CompletedTask;
    }

    private Task OnTreeItemChecked(TreeItem item)
    {
        var state = item.Checked ? "选中" : "未选中";
        TraceChecked.Log($"TreeItem: {item.Text} {state}");
        return Task.CompletedTask;
    }

    private static async Task OnExpandNode(TreeItem item)
    {
        if (!item.Items.Any() && item.HasChildNode && !item.ShowLoading)
        {
            item.ShowLoading = true;
            if (item.Key?.ToString() == "Delay")
            {
                await Task.Delay(800);
            }
            item.Items.AddRange(new TreeItem[]
            {
                    new TreeItem()
                    {
                        Text = "懒加载子节点1",
                        HasChildNode = true
                    },
                    new TreeItem() { Text = "懒加载子节点2" }
            });
            item.ShowLoading = false;
        }
    }

    private Task OnTreeItemChecked(List<TreeItem> items)
    {
        TraceCheckedItems.Log($"当前共选中{items.Count}项");
        return Task.CompletedTask;
    }

    /// <summary>
    /// 获得属性方法
    /// </summary>
    /// <returns></returns>
    private static IEnumerable<AttributeItem> GetAttributes() => new AttributeItem[]
    {
        // TODO: 移动到数据库中
        new AttributeItem() {
            Name = "Items",
            Description = "菜单数据集合",
            Type = "IEnumerable<TreeItem>",
            ValueList = " — ",
            DefaultValue = "new List<TreeItem>(20)"
        },
        new AttributeItem() {
            Name = "ClickToggleNode",
            Description = "是否点击节点时展开或者收缩子项",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowCheckbox",
            Description = "是否显示 CheckBox",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowIcon",
            Description = "是否显示 Icon",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowSkeleton",
            Description = "是否显示加载骨架屏",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "OnTreeItemClick",
            Description = "树形控件节点点击时回调委托",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "OnTreeItemChecked",
            Description = "树形控件节点选中时回调委托",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "OnExpandNode",
            Description = "树形控件节点展开回调委托",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "OnCheckedItems",
            Description = "树形控件获取所有选中节点回调委托",
            Type = "Func<List<TreeItem>, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        }
    };

    private static IEnumerable<AttributeItem> GetTreeItemAttributes() => new AttributeItem[]
    {
        // TODO: 移动到数据库中
        new AttributeItem() {
            Name = nameof(TreeItem.Key),
            Description = "TreeItem 标识",
            Type = "object?",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "Items",
            Description = "子节点数据源",
            Type = "IEnumerable<TreeItem>",
            ValueList = " — ",
            DefaultValue = "new List<TreeItem>(20)"
        },
        new AttributeItem() {
            Name = "Text",
            Description = "显示文字",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "Icon",
            Description = "显示图标",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "CssClass",
            Description = "节点自定义样式",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "Checked",
            Description = "是否被选中",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = nameof(TreeItem.IsDisabled),
            Description = "是否被禁用",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "IsCollapsed",
            Description = "是否展开",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "true"
        },
        new AttributeItem() {
            Name = nameof(TreeItem.Tag),
            Description = "TreeItem 附加数据",
            Type = "object?",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = nameof(TreeItem.HasChildNode),
            Description = "是否有子节点",
            Type = "bool",
            ValueList = " true|false ",
            DefaultValue = " false "
        },
        new AttributeItem() {
            Name = nameof(TreeItem.ShowLoading),
            Description = "是否显示子节点加载动画",
            Type = "bool",
            ValueList = " true|false ",
            DefaultValue = " false "
        },
        new AttributeItem()
        {
            Name = nameof(TreeItem.Template),
            Description = "子节点模板",
            Type = nameof(RenderFragment),
            ValueList = " — ",
            DefaultValue = " — "
        }
    };
}

B 站相关视频链接

暂无

交流群

QQ Group:BootstrapAdmin & Blazor 795206915 675147445 Welcome to join the group discussion
Themes
Bootstrap
Motronic
Ant Design (完善中)
LayUI (完善中)
An error has occurred. This application may no longer respond until reloaded. Reload
Seems like the connection with the server has been lost. It can be due to poor or broken network. Please hang on while we're trying to reconnect...
Oh snap! Failed to reconnect with the server. This is typically caused by a longer network outage, or if the server has been taken down. You can try to reconnect, but if that does not work, you need to reload the page.
Oh man! The server rejected the attempt to reconnect. The only option now is to reload the page, but be prepared that it won't work, since this is typically caused by a failure on the server.
Bootstrap Blazor 组件库 更新到 6.6.0

首先感谢您对本套组件的关注,本目前本套组件已经拥有超过 120 个组件,本组件是基于 Bootstrap 风格的 Blazor 企业级组件库,提供如布局、导航、表单、数据、通知、图标、语音等几大类通用组件,每一个组件都经过静心设计,具有模块化、响应式和优秀的性能。从更多实际场景出发,满足多种场景的需求,极大的减少开发者时间成本,大大缩短开发周期,大幅提高开发效率,并提供了一套 通用权限管理系统 示例工程。Bootstrap Blazor 产品是由一支专业的全职技术团队进行维护,高效的响应速度,多元化的解决方案,长期提供支持,并提供企业级支持。目前已在多家知名国企内部使用,项目最高在线 1200 人稳定运行。右侧为国内人数最多的中文 Blazor QQ 社区二维码,欢迎扫描加群。

组件更新到 6.6.0 更新日志 [传送门] 如果组件给您带来了方便,请您帮忙给项目点亮 Star github gitee

QQGroup
QQ 795206915