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

Tree tree control

Present information in a clear hierarchy that can be expanded or collapsed

Basic tree structure display

Demo

By setting the OnTreeItemClick property to monitor the event when the tree control node is clicked, the following log displays the data of the selected node when the tree control node is clicked

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

Suitable for use when you need to select a level

Demo

By setting the OnTreeItemChecked property to monitor the event when the tree control node is checked, when the check box in front of the tree control node is selected, the following log displays the data of the selected node

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

For single-select nodes

Demo

Show the Radio component in front of the node by setting the ShowRadio property

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

Some nodes of the Tree can be set to disabled state

Demo

By setting the Disabled property of the data source TreeItem object, you can control whether this node can be checked or not. When set to false, it will not affect the node expansion. /shrink function

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

For nodes of the same level, only one can be expanded at a time

Demo

Enable the accordion effect by setting the IsAccordion property of the Tree component

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

Some nodes of Tree can be set to be expanded or selected by default

Demo

By setting the IsCollapsed property of the TreeItem object, you can control whether this node is in the expanded state by default. In this example, navigation two is in the expanded state by default, and the rest Node defaults to contracted state

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

Control whether the component displays the icon by setting ShowIcon

Demo

By setting the ShowIcon property of the TreeItem object, you can control whether this node displays the icon or not

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

By setting ClickToggleNode to control whether to expand and contract when the node is clicked

Demo

By setting the ClickToggleNode property of the TreeItem object, you can control whether this node can be expanded and contracted by clicking

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

Tree can be enabled inside the component Checkbox will be displayed when it is built into the validation form DisplayName This function needs to be disabled in the tree component

Demo

Show Checkbox built into validation component ValidateForm by setting ShowCheckbox property does not show DisplayName

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

Dynamically add child nodes when expanding a node

Demo

By setting the node HasChildNode to control whether to display the small arrow picture of the node. Add nodes through Tree's OnExpandNode delegate

  • 导航一
  • 导航二
    • 子菜单一
    • lazy loading
      • 孙菜单一
      • 孙菜单二
        • 曾孙菜单一
          • 曾曾孙菜单一
          • 曾曾孙菜单二
          • 曾曾孙菜单三
        • 曾孙菜单二
        • 曾孙菜单三
      • 孙菜单三
    • lazy loading delay
  • 导航三

Implement your own node template by setting TreeItem Template

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

Implement your own node style by setting TreeItem CssClass

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

Get all nodes by setting the OnTreeItemChecked callback delegate

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

By setting ShowSkeleton, the component displays the skeleton screen when the data is loaded asynchronously

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

Attributes

Loading...

TreeItem property

Loading...
@page "/trees"
@inject IStringLocalizer<Trees> Localizer

<h3>Tree tree control</h3>
<h4>Present information in a clear hierarchy that can be expanded or collapsed</h4>

<Tips class="mt-3">
    <p>Obsolete,The <a href="treeviews" alt="treeview">TreeView</a> provides more functions
</Tips>

<DemoBlock Title="Basic usage" Introduction="Basic tree structure display" Name="Normal">
    <p>
        By setting the <code>OnTreeItemClick</code> property to monitor the event when the tree control node is clicked, the following log displays the data of the selected node when the tree control node is clicked
    </p>
    <Tree Items="@Items" OnTreeItemClick="@OnTreeItemClick" />
    <BlockLogger @ref="Trace" class="mt-3" />
</DemoBlock>

<DemoBlock Title="Checkbox" Introduction="Suitable for use when you need to select a level" Name="Checkbox">
    <p>
        By setting the <code>OnTreeItemChecked</code> property to monitor the event when the tree control node is checked, when the check box in front of the tree control node is selected, the following log displays the data of the selected node
    </p>
    <Tree Items="@CheckedItems" ShowCheckbox="true" OnTreeItemChecked="@OnTreeItemChecked" />
    <BlockLogger @ref="TraceChecked" class="mt-3" />
</DemoBlock>

<DemoBlock Title="Single box" Introduction="For single-select nodes" Name="ShowRadio">
    <p>
        Show the <code>Radio</code> component in front of the node by setting the <code>ShowRadio</code> property
    </p>
    <Tree Items="@CheckedItems" ShowRadio="true" />
</DemoBlock>

<DemoBlock Title="disabled state" Introduction="Some nodes of the Tree can be set to disabled state" Name="TreeDisable">
    <p>
        By setting the <code>Disabled</code> property of the data source <code>TreeItem</code> object, you can control whether this node can be checked or not. When set to <code>false</code>, it will not affect the node expansion. /shrink function
    </p>
    <Tree Items="@DisabledItems" ShowCheckbox="true" />
</DemoBlock>

<DemoBlock Title="Accordion mode" Introduction="For nodes of the same level, only one can be expanded at a time" Name="AccordionModel">
    <p>Enable the accordion effect by setting the <code>IsAccordion</code> property of the <code>Tree</code> component</p>
    <Tree Items="@Items" ShowCheckbox="true" IsAccordion="true" />
</DemoBlock>

<DemoBlock Title="Expanded by default and selected by default" Introduction="Some nodes of <code>Tree</code> can be set to be expanded or selected by default" Name="DefauleExpand">
    <p>
        By setting the <code>IsCollapsed</code> property of the <code>TreeItem</code> object, you can control whether this node is in the expanded state by default. In this example, <b>navigation two</b> is in the expanded state by default, and the rest Node defaults to contracted state
    </p>
    <Tree Items="@ExpandItems" ShowCheckbox="true" />
</DemoBlock>

<DemoBlock Title="show icon" Introduction="Control whether the component displays the icon by setting <code>ShowIcon</code>" Name="TreeDisplayIcon">
    <p>
        By setting the <code>ShowIcon</code> property of the <code>TreeItem</code> object, you can control whether this node displays the icon or not
    </p>
    <Tree Items="@GetIconItems()" ShowIcon="true" ShowCheckbox="true" />
</DemoBlock>

<DemoBlock Title="Click on the node to expand and contract" Introduction="By setting <code>ClickToggleNode</code> to control whether to expand and contract when the node is clicked" Name="TreeClickExpand">
    <p>
        By setting the <code>ClickToggleNode</code> property of the <code>TreeItem</code> object, you can control whether this node can be expanded and contracted by clicking
    </p>
    <Tree Items="@Items" ShowIcon="true" ShowCheckbox="true" ClickToggleNode="true" />
</DemoBlock>

<DemoBlock Title="The Tree component is built into the validation form" Introduction="<code>Tree</code> can be enabled inside the component <code>Checkbox</code> will be displayed when it is built into the validation form <code>DisplayName</code> This function needs to be disabled in the tree component" Name="TreeValidationForm">
    <p>
        Show <code>Checkbox</code> built into validation component <code>ValidateForm</code> by setting <code>ShowCheckbox</code> property does not show <code>DisplayName</code>
    </p>
    <ValidateForm Model="@Model">
        <Tree Items="@Items" OnTreeItemClick="@OnTreeItemClick" ShowCheckbox="true" />
    </ValidateForm>
</DemoBlock>

<DemoBlock Title="lazy loading" Introduction="Dynamically add child nodes when expanding a node" Name="TreeLazyLoading">
    <p>
        By setting the node <code>HasChildNode</code> to control whether to display the small arrow picture of the node. Add nodes through Tree's <code>OnExpandNode</code> delegate
    </p>
    <Tree ClickToggleNode="true" Items="@GetLazyItems()" OnExpandNode="OnExpandNode" />
</DemoBlock>

<DemoBlock Title="custom node" Introduction="Implement your own node template by setting <code>TreeItem</code> <code>Template</code>" Name="TreeCustomNode">
    <Tree ClickToggleNode="true" Items="GetTemplateItems()" />
</DemoBlock>

<DemoBlock Title="node color" Introduction="Implement your own node style by setting <code>TreeItem</code> <code>CssClass</code>" Name="TreeNodeColor">
    <Tree ClickToggleNode="true" Items="GetColorItems()" />
</DemoBlock>

<DemoBlock Title="Get all selected nodes" Introduction="Get all nodes by setting the <code>OnTreeItemChecked</code> callback delegate" Name="CheckedItems">
    <Tree ShowCheckbox="true" Items="@Items" OnTreeItemChecked="@OnTreeItemChecked" />
    <BlockLogger @ref="TraceCheckedItems" class="mt-3" />
</DemoBlock>

<DemoBlock Title="loading skeleton screen" Introduction="By setting <code>ShowSkeleton</code>, the component displays the skeleton screen when the data is loaded asynchronously" Name="ShowSkeleton">
    <Button Text="Asynchronous loading" IsAsync="true" Icon="fa-solid fa-font-awesome" OnClick="OnLoadAsyncItems" />
    <Tree Items="@AsyncItems" ShowSkeleton="true" class="mt-3" />
</DemoBlock>

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

<AttributeTable Items="@GetTreeItemAttributes()" Title="TreeItem property" />
// 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 Microsoft.AspNetCore.Components.Rendering;
using Microsoft.AspNetCore.Components.Web;

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>? LocalizerFoo { get; set; }

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

    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 = "lazy loading";
        ret[1].Items[1].HasChildNode = true;
        ret[1].Items[2].Text = "lazy loading delay";
        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-solid fa-font-awesome");
            builder.AddAttribute(2, nameof(Button.Text), "Click");
            builder.AddAttribute(3, nameof(Button.OnClick), EventCallback.Factory.Create<MouseEventArgs>(this, e =>
            {
                ToastService.Warning("Custom TreeItem", "Test the TreeItem button click event");
            }));
            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 ? "checked" : "Unselected";
        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 = "lazy loading child node 1",
                        HasChildNode = true
                    },
                    new TreeItem() { Text = "lazy loading child node 2" }
            });
            item.ShowLoading = false;
        }
    }

    private Task OnTreeItemChecked(List<TreeItem> items)
    {
        TraceCheckedItems.Log($"Currently selected {items.Count} item");
        return Task.CompletedTask;
    }

    /// <summary>
    /// 获得属性方法
    /// </summary>
    /// <returns></returns>
    private static IEnumerable<AttributeItem> GetAttributes() => new AttributeItem[]
    {
        new AttributeItem() {
            Name = "Items",
            Description = "Menu data set",
            Type = "IEnumerable<TreeItem>",
            ValueList = " — ",
            DefaultValue = "new List<TreeItem>(20)"
        },
        new AttributeItem() {
            Name = "ClickToggleNode",
            Description = "Whether to expand or contract children when a node is clicked",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowCheckbox",
            Description = "Whether to display CheckBox",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowIcon",
            Description = "Whether to display Icon",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowSkeleton",
            Description = "Whether to display the loading skeleton screen",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "OnTreeItemClick",
            Description = "Callback delegate when tree control node is clicked",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "OnTreeItemChecked",
            Description = "Callback delegate when tree control node is selected",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "OnExpandNode",
            Description = "Tree control node expand callback delegate",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "OnCheckedItems",
            Description = "The tree control gets the callback delegate of all selected nodes",
            Type = "Func<List<TreeItem>, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        }
    };

    private static IEnumerable<AttributeItem> GetTreeItemAttributes() => new AttributeItem[]
    {
        new AttributeItem() {
            Name = nameof(TreeItem.Key),
            Description = "TreeItem ID",
            Type = "object?",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "Items",
            Description = "Child node data source",
            Type = "IEnumerable<TreeItem>",
            ValueList = " — ",
            DefaultValue = "new List<TreeItem>(20)"
        },
        new AttributeItem() {
            Name = "Text",
            Description = "Display text",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "Icon",
            Description = "Show icon",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "CssClass",
            Description = "Node custom style",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "Checked",
            Description = "Is selected",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = nameof(TreeItem.IsDisabled),
            Description = "Is disabled",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "IsCollapsed",
            Description = "Whether to expand",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "true"
        },
        new AttributeItem() {
            Name = nameof(TreeItem.Tag),
            Description = "TreeItem Additional data",
            Type = "object?",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = nameof(TreeItem.HasChildNode),
            Description = "Whether there are child nodes",
            Type = "bool",
            ValueList = " true|false ",
            DefaultValue = " false "
        },
        new AttributeItem() {
            Name = nameof(TreeItem.ShowLoading),
            Description = "Whether to show child node loading animation",
            Type = "bool",
            ValueList = " true|false ",
            DefaultValue = " false "
        },
        new AttributeItem()
        {
            Name = nameof(TreeItem.Template),
            Description = "Child node template",
            Type = nameof(RenderFragment),
            ValueList = " — ",
            DefaultValue = " — "
        }
    };
}

B station related video link

No

交流群

QQ Group:BootstrapAdmin & Blazor 795206915 675147445 Welcome to join the group discussion
img
Themes
Bootstrap
Motronic
Ant Design (完善中)
DevUI (制作中)
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 Component library updated to 7.0.8-beta05

Bootstrap Blazor at present has more than 120 components. This component is based on Bootstrap Blazor An enterprise-level component library that provides several types of common components such as layout, navigation, form, data, notification, icon, voice, etc. Each component has been carefully designed with modularity, responsiveness and excellent performance. Starting from more practical scenarios, meeting the needs of various scenarios, greatly reducing the time cost of developers, greatly shortening the development cycle, greatly improving development efficiency, and providing a set of General Rights Management System Example project。Bootstrap Blazor Products are maintained by a professional full-time technical team, with efficient response speed, diversified solutions, long-term support, and enterprise-level support. At present, it has been used in many well-known state-owned enterprises, and the project is running stably with a maximum of 1200 people online. On the right is the QR code of the Chinese Blazor QQ community with the largest number of people in China, welcome to scan and join the group.

component updated to 6.6.0 Change log [portal] If the component brings you convenience, please help to light up the project Star github gitee

QQGroup
QQ 795206915