Blazor 生态里,BootstrapBlazor 是用得最多的 Bootstrap 风格 UI 组件库之一。v10.6.1 版本虽然标注为 Bugfix,但修的两个 Table 问题都踩在实际开发的高频痛点上——二次渲染参数丢失和高度自适应异常。如果你项目里用了 Table 组件做数据展示,这个版本值得立刻升级。
二次渲染时 TableColumn 参数"消失"了
TableColumn 支持在首次渲染后动态修改参数(比如切换列的可见性、调整宽度),这在做动态列配置、权限控制列显隐时很常见。但之前的版本里,二次渲染时部分参数会被"吞掉"——你设了新值,组件内部还是用旧值。
典型场景:用户点击按钮隐藏某列,你把 Visible 改成 false,首次生效,再切换回来时列却不再出现。根因是 TableColumn 在二次渲染流程中没有正确重新同步参数到内部状态。
修复 PR #7966 由 @Tony-ST0754 提交,核心改动是确保每次渲染都重新读取外部传入的参数值,而不是只在初始化时读一次。
下面这段代码演示了动态切换列可见性的正确用法(升级到 v10.6.1 后才能稳定生效):
@page "/table-demo"
<BootstrapBlazor.Table Items="@employees"
IsPagination="true"
PageItemsSource="@pageItems">
<TableColumns>
<TableColumn @bind-Field="@context.Name" Visible="@showNameColumn" />
<TableColumn @bind-Field="@context.Department" />
<TableColumn @bind-Field="@context.Salary" Visible="@showSalaryColumn" />
</TableColumns>
</BootstrapBlazor.Table>
<div class="mt-3">
<BootstrapBlazor.Button Text="切换姓名列" OnClick="ToggleNameColumn" />
<BootstrapBlazor.Button Text="切换薪资列" OnClick="ToggleSalaryColumn" />
</div>
@code {
private List<Employee> employees = new()
{
new() { Name = "张三", Department = "研发部", Salary = 15000 },
new() { Name = "李四", Department = "市场部", Salary = 12000 },
new() { Name = "王五", Department = "运维部", Salary = 13000 }
};
private IEnumerable<int> pageItems = new[] { 5, 10, 20 };
private bool showNameColumn = true;
private bool showSalaryColumn = true;
private void ToggleNameColumn() => showNameColumn = !showNameColumn;
private void ToggleSalaryColumn() => showSalaryColumn = !showSalaryColumn;
public class Employee
{
public string Name { get; set; } = "";
public string Department { get; set; } = "";
public decimal Salary { get; set; }
}
}
升级前,反复点击按钮后列可能"卡死"在隐藏状态;升级后,每次切换都能正确响应。
表格高度自适应终于靠谱了
另一个修复是 Table 高度自适应计算不准。当表格放在弹性布局容器里(比如侧边栏 + 主内容区,主内容区高度由 flex: 1 决定),Table 设置了 IsAutoHeight="true" 后,实际渲染高度经常溢出或留白。
原因在于组件读取容器高度的时机和方式有问题——有时拿到的是尚未完成布局的中间值,有时干脆没考虑父容器的 padding / border。
修复后,Table 会在布局稳定后重新计算可用高度,并扣除容器边距,表格不再撑破页面也不留大片空白。
一个常见的自适应布局用法:
@page "/flex-table"
<!-- 外层 flex 容器,撑满视口 -->
<div style="display:flex; flex-direction:column; height:100vh;">
<!-- 顶部工具栏 -->
<div style="height:48px; padding:8px; background:#f8f9fa;">
<BootstrapBlazor.Button Text="刷新数据" OnClick="RefreshData" />
</div>
<!-- 表格区自动占满剩余高度 -->
<div style="flex:1; overflow:hidden; padding:0 8px 8px;">
<BootstrapBlazor.Table Items="@data"
IsAutoHeight="true"
IsPagination="true"
PageItemsSource="@pageItems" />
</div>
</div>
@code {
private List<Record> data = Enumerable.Range(1, 50)
.Select(i => new Record { Id = i, Title = $"记录 {i}", Created = DateTime.Now.AddDays(-i) })
.ToList();
private IEnumerable<int> pageItems = new[] { 10, 20, 50 };
private void RefreshData()
{
// 实际项目中这里调用 API 重新拉数据
data = Enumerable.Range(1, 50)
.Select(i => new Record { Id = i, Title = $"刷新记录 {i}", Created = DateTime.Now })
.ToList();
}
public class Record
{
public int Id { get; set; }
public string Title { get; set; } = "";
public DateTime Created { get; set; }
}
}
关键点:IsAutoHeight="true" 配合 flex:1 的父容器,升级后表格高度才会精确填满可用空间,不会多一行也不会少一行。
升级与验证清单
升级步骤很简单,但建议按以下顺序验证:
# 1. 升级 NuGet 包
dotnet add package BootstrapBlazor --version 10.6.1
# 2. 确认引用版本
dotnet list package
升级后重点检查这几项:
- 动态列显隐:所有用
Visible/IsReadonly等参数做二次切换的 TableColumn,反复切换是否正常。 - 自适应高度表格:放在 flex 或绝对定位容器里的
IsAutoHeight表格,滚动条是否正确出现,底部是否被截断。 - 自定义渲染列:如果 TableColumn 用了
Template自定义渲染模板,二次渲染后模板内容是否还完整。
如果项目暂时没法升级,动态列的临时 workaround 是在切换参数后手动调用 StateHasChanged() 并给 TableColumn 加 @key 强制重建组件,而不是依赖参数更新:
<!-- workaround:用 @key 强制重建,绕过参数不生效 -->
<TableColumn @key="@showNameColumn" @bind-Field="@context.Name" Visible="@showNameColumn" />
代价是每次切换都会销毁重建列组件,性能略有损耗,但功能上能跑。
两个修复都不大,但都卡在日常开发的高频路径上。用 Table 做动态列或自适应布局的项目,建议直接升到 v10.6.1,省掉 workaround 的心智负担。