如何在Blazor .NET Core应用中基于MudBlazor实现通用泛型表格组件
基于MudBlazor实现泛型通用动态表格方案
实现思路
本次实现的通用组件同时支持强类型IEnumerable<T>和DataTable两类数据源,内置MudTable原生的分页、排序、搜索、行操作能力,可直接在业务页面复用无需重复编写表格结构代码。
第一步:定义公共列配置类
public class TableColumnConfig { /// <summary> /// 数据源对应的属性名/列名 /// </summary> public string FieldName { get; set; } /// <summary> /// 表格表头显示名称 /// </summary> public string DisplayName { get; set; } /// <summary> /// 是否支持排序 /// </summary> public bool Sortable { get; set; } = true; /// <summary> /// 列宽 /// </summary> public string? Width { get; set; } /// <summary> /// 自定义渲染模板,为空则默认渲染字段值 /// </summary> public RenderFragment<object>? CellTemplate { get; set; } }
第二步:创建泛型通用表格组件 GenericMudTable.razor
@typeparam TItem @using System.Data @using System.Reflection <MudTable Items="@FinalDataSource" Hover="true" Sortable="true" Pagination="true" RowsPerPage="10" RowClick="OnRowClick.InvokeAsync" Class="mt-4"> <HeaderContent> @foreach (var col in ColumnConfigs) { <MudTh SortLabel="@col.FieldName" Width="@col.Width">@col.DisplayName</MudTh> } </HeaderContent> <RowTemplate> @{ var rowData = context; foreach (var col in ColumnConfigs) { <MudTd> @if (col.CellTemplate != null) { @col.CellTemplate(rowData) } else { @GetCellValue(rowData, col.FieldName) } </MudTd> } } </RowTemplate> </MudTable> @code { /// <summary> /// 强类型列表数据源 /// </summary> [Parameter] public IEnumerable<TItem>? DataSource { get; set; } /// <summary> /// DataTable格式数据源 /// </summary> [Parameter] public DataTable? DataTableSource { get; set; } /// <summary> /// 列配置 /// </summary> [Parameter, Required] public List<TableColumnConfig> ColumnConfigs { get; set; } = new(); /// <summary> /// 行点击回调 /// </summary> [Parameter] public EventCallback<TItem> OnRowClick { get; set; } private IEnumerable<object>? FinalDataSource { get; set; } private Dictionary<Type, PropertyInfo[]> _propertyCache = new(); protected override void OnParametersSet() { base.OnParametersSet(); // 合并处理两类数据源 if (DataSource != null) { FinalDataSource = DataSource.Cast<object>(); } else if (DataTableSource != null) { FinalDataSource = DataTableSource.AsEnumerable(); } } private object? GetCellValue(object rowData, string fieldName) { if (rowData is DataRow dataRow) { return dataRow[fieldName] == DBNull.Value ? null : dataRow[fieldName]; } // 反射缓存优化性能 var type = rowData.GetType(); if (!_propertyCache.TryGetValue(type, out var props)) { props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); _propertyCache[type] = props; } var prop = props.FirstOrDefault(p => p.Name == fieldName); return prop?.GetValue(rowData); } }
第三步:组件使用示例
场景1:绑定强类型List
// 定义业务实体类 public class User { public int Id { get; set; } public string UserName { get; set; } public DateTime CreateTime { get; set; } public bool IsActive { get; set; } }
页面调用代码:
@page "/userlist" <GenericMudTable TItem="User" DataSource="@UserList" ColumnConfigs="@UserColumns" OnRowClick="HandleUserClick"> </GenericMudTable> @code { private List<User> UserList { get; set; } = new(); private List<TableColumnConfig> UserColumns { get; set; } = new(); protected override void OnInitialized() { // 初始化列配置 UserColumns = new List<TableColumnConfig> { new TableColumnConfig { FieldName = "Id", DisplayName = "用户ID", Width = "80px" }, new TableColumnConfig { FieldName = "UserName", DisplayName = "用户名" }, new TableColumnConfig { FieldName = "CreateTime", DisplayName = "创建时间" }, // 自定义列模板示例 new TableColumnConfig { FieldName = "IsActive", DisplayName = "状态", CellTemplate = (row) =>@<MudChip Color="@((bool)((User)row).IsActive ? Color.Success : Color.Default)">@(((User)row).IsActive ? "启用" : "禁用")</MudChip> } }; // 模拟加载数据 UserList = Enumerable.Range(1, 20).Select(i => new User { Id = i, UserName = $"用户{i}", CreateTime = DateTime.Now.AddDays(-i), IsActive = i % 2 == 0 }).ToList(); } private void HandleUserClick(User user) { // 行点击逻辑,比如跳转到详情页 Console.WriteLine($"点击了用户:{user.UserName}"); } }
场景2:绑定DataTable数据源
@page "/datatable-demo" <GenericMudTable TItem="DataRow" DataTableSource="@DemoDataTable" ColumnConfigs="@DataTableColumns"> </GenericMudTable> @code { private DataTable DemoDataTable { get; set; } = new(); private List<TableColumnConfig> DataTableColumns { get; set; } = new(); protected override void OnInitialized() { // 构造测试DataTable DemoDataTable.Columns.Add("订单号", typeof(string)); DemoDataTable.Columns.Add("商品名称", typeof(string)); DemoDataTable.Columns.Add("金额", typeof(decimal)); for (int i = 1; i <= 15; i++) { var row = DemoDataTable.NewRow(); row["订单号"] = $"OD{i.ToString().PadLeft(6, '0')}"; row["商品名称"] = $"商品{i}"; row["金额"] = i * 100.5m; DemoDataTable.Rows.Add(row); } // 列配置和DataTable列名对应即可 DataTableColumns = new List<TableColumnConfig> { new TableColumnConfig { FieldName = "订单号", DisplayName = "订单编号" }, new TableColumnConfig { FieldName = "商品名称", DisplayName = "商品" }, new TableColumnConfig { FieldName = "金额", DisplayName = "订单金额" } }; } }
扩展优化建议
- 可以新增参数控制是否显示搜索框、是否可多选、行高、斑马纹等MudTable原生属性,直接透传即可
- 反射部分可替换为表达式树编译的属性访问器,进一步提升大数据量下的渲染性能
- 可新增全局默认配置,比如默认每页行数、默认排序字段等
内容的提问来源于stack exchange,提问作者Bharath Kumar
相关产品推荐
相关产品推荐

