接上篇: B08. BootstrapBlazor实战 Menu 导航菜单使用(1)
实战BootstrapBlazorMenu 导航菜单的使用, 以及整合Freesql orm快速制作菜单项数据库后台维护页面
BootstrapBlazor 是 Bootstrap 风格的 Blazor UI 组件库 基于 Bootstrap 样式库精心打造,并且额外增加了 100 多种常用的组件,为您快速开发项目带来非一般的感觉
demo演示的是Sqlite驱动,FreeSql支持多种数据库,MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/神通/人大金仓/翰高/华为GaussDB/MsAccess
节省时间,直接使用 Bootstrap Blazor App 模板快速搭建项目
传送门:https://www.blazor.zone/template
dotnet new -i Bootstrap.Blazor.Templates
dotnet new bbapp
dotnet new bbapp -o b08Menu dotnet add b08Menu/BootstrapBlazorApp.Shared package FreeSql.Provider.Sqlite dotnet add b08Menu/BootstrapBlazorApp.Shared package Densen.FreeSql.Extensions.BootstrapBlazor dotnet sln add b08Menu/BootstrapBlazorApp.Server/BootstrapBlazorApp.Server.csproj dotnet sln add b08Menu/BootstrapBlazorApp.Shared/BootstrapBlazorApp.Shared.csproj dotnet sln add b08Menu/BootstrapBlazorApp.WebAssembly/BootstrapBlazorApp.WebAssembly.csproj
注:由于模板使用了共享库,双出Server
和WebAssembly
工程,我们这里只使用Server
工程做演示.
添加FreeSql服务到BootstrapBlazorApp.Server/Program.cs
在 builder.Services.AddBootstrapBlazor(); 之前加入
builder.Services.AddFreeSql(option => { //demo演示的是Sqlite驱动,FreeSql支持多种数据库,MySql/SqlServer/PostgreSQL/Oracle/Sqlite/Firebird/达梦/神通/人大金仓/翰高/华为GaussDB/MsAccess option.UseConnectionString(FreeSql.DataType.Sqlite, "Data Source=test.db;") //也可以写到配置文件中 #if DEBUG //开发环境:自动同步实体 .UseAutoSyncStructure(true) .UseNoneCommandParameter(true) //调试sql语句输出 .UseMonitorCommand(cmd => System.Console.WriteLine(cmd.CommandText)) #endif ; });
传送门:https://github.com/densen2014/Blazor100/wiki/B03.-BootstrapBlazor实战-10分钟编写数据库维护项目
使用FreeSql的父子导航属性处理树形分类
传送门:https://github.com/densen2014/Blazor100/wiki/B05.-BootstrapBlazor实战-Tree树形控件使用(2)
新建类文件 Data/WebPages.cs
/// <summary> /// 页面 /// </summary> [AutoGenerateClass(Searchable = true, Filterable = true, Sortable = true)] public class WebPages { public WebPages() { } public WebPages(string PageName, string? Url = null, string? Icon = null, string? Code = "0", List<WebPages>? Childs = null) { this.PageName = PageName; this.Url = Url ?? $"/{PageName}"; this.Icon = Icon; this.Code = Code; this.Childs = Childs; } /// <summary> ///代码 /// </summary> [DisplayName("代码")] [Column(IsPrimary = true)] [AutoGenerateColumn(DefaultSort = true, DefaultSortOrder = SortOrder.Asc)] public string? Code { get; set; } /// <summary> ///父级代码 /// </summary> [DisplayName("父级代码")] [Column] public string? ParentCode { get; set; } [Navigate(nameof(ParentCode))] [AutoGenerateColumn(Ignore = true)] public WebPages? Parent { get; set; } [Navigate(nameof(ParentCode))] [AutoGenerateColumn(Ignore = true)] public List<WebPages>? Childs { get; set; } /// <summary> ///页面名称 /// </summary> [Required(ErrorMessage = "{0}不能为空")] [DisplayName("页面名称")] public string? PageName { get; set; } /// <summary> ///Icon /// </summary> [DisplayName("Icon")] [AutoGenerateColumn(Visible = false)] public string? Icon { get; set; } /// <summary> ///Url /// </summary> [Required(ErrorMessage = "{0}不能为空")] [DisplayName("Url")] [AutoGenerateColumn(Visible = false)] public string? Url { get; set; } /// <summary> /// 隐藏 /// </summary> [DisplayName ("隐藏")] public bool Hide { get; set; } }
写文章的时候这个方法已经pr进BootstrapBlazor库,可能读者们看到的时候已经内置次方法了.如果重复,自行跳过这步.
public static class Utility { /// <summary> /// 菜单树状数据层次化方法 /// </summary> /// <param name="items">数据集合</param> /// <param name="parentId">父级节点</param> public static IEnumerable<MenuItem> CascadingMenu(this IEnumerable<MenuItem> items, string? parentId = null) => items.Where(i => i.ParentId == parentId).Select(i => { i.Items = CascadingMenu(items, i.Id).ToList(); return i; }); }
找到BootstrapBlazorApp.Shared/Shared/MainLayout.razor
文件,展开三角符号,打开MainLayout.razor.cs
文件编辑
注入FreeSql
[Inject] [NotNull] IFreeSql? fsql { get; set; }
Menus 初始化保存到数据库
using Microsoft.AspNetCore.Components; using System.Diagnostics.CodeAnalysis; using BootstrapBlazorApp.Shared.Data; //private List<MenuItem>? Menus { get; set; } private List<MenuItem>? Menus { get; set; } = new List<MenuItem>(); /// <summary> /// OnInitialized 方法 /// </summary> protected override void OnInitialized() { base.OnInitialized(); //Menus = GetIconSideMenuItems(); } protected override void OnAfterRender(bool firstRender) { if (firstRender) { if (fsql.Select<WebPages>().Count() == 0) { var pages = new List<WebPages>(){ new WebPages("首页","/","fa fa-home","001") , new WebPages("数据","","fa fa-fw fa-database","002", new List<WebPages>(new[] { new WebPages("FetchData","fetchdata","fa fa-fw fa-database","002_001") , new WebPages( "Counter","counter","fa fa-fw fa-check-square-o","002_002") , new WebPages("后台管理","admins","fa fa-gears","002_003") , })) , new WebPages("Table","table","fa fa-fw fa-table","004") , new WebPages("花名册","users","fa fa-fw fa-users","005") }; var repo = fsql.GetRepository<WebPages>();//仓库类 repo.DbContextOptions.EnableAddOrUpdateNavigateList = true; //开启一对多,多对多级联保存功能 repo.Insert(pages); } Menus = fsql.Select<WebPages>().OrderBy(a => a.Code) .LeftJoin(d => d.ParentCode == d.Parent!.Code) .ToList(a => new MenuItem() { Text = a.PageName, Id = a.Code, Url = a.Url, ParentId = a.ParentCode, Icon = a.Icon }).CascadingMenu().ToList(); // 算法获取属性结构数据 .CascadingMenu().ToList() StateHasChanged(); } }
到这一步,大家肯定迫不及待要运行一下了,来吧,少年,F5
使用Densen.FreeSql.Extensions.BootstrapBlazor
库的数据库服务直接表格编辑菜单数据库表格.
先注销模板工程自带演示服务,BootstrapBlazorApp.Server/Program.cs
注销builder.Services.AddTableDemoDataService();
// 增加 Table 数据服务操作类 //builder.Services.AddTableDemoDataService();
新建BootstrapBlazorApp.Shared/Pages/Admins.razor
文件
@page "/admins" @attribute [TabItemOption(Text = "菜单管理")] <PageTitle>菜单管理</PageTitle> <div class="table-users scroll"> <Table TItem="WebPages" IsFixedHeader="true" IsPagination="true" IsStriped="true" AutoGenerateColumns="true" ShowSearch="true" ShowToolbar="true" ShowExtendButtons="true" DoubleClickToEdit=true ShowColumnList=true ShowCardView=true> </Table> </div>
来吧,少年,F5
是不是很有成就感,你怎么这么优秀呢? 哈哈哈.
刷新页面
少年, 如期而来!