Blazor实现无限滚动:动态加载数据项
仅用Blazor(.NET 7.0)实现滚动到底部自动加载数据
当然可以完全不用额外编写自定义JavaScript,仅通过Blazor自身的组件机制和内置API实现滚动加载功能。核心思路是监听滚动容器的滚动事件,判断是否到达底部,触发分页数据加载。
完整实现示例
1. 组件核心变量与数据方法
首先在组件中定义分页相关变量,以及实际的数据获取方法(以下示例用模拟数据替代):
@code { private List<DataItem> _dataItems = new(); private int _currentPage = 1; private const int PageSize = 15; private bool _isLoading = false; private readonly string _scrollContainerId = "data-scroll-container"; // 替换为你的实际数据获取逻辑(API调用、数据库查询等) private async Task<List<DataItem>> FetchPageData(int page, int pageSize) { // 模拟网络延迟 await Task.Delay(400); // 生成测试数据 return Enumerable.Range((page - 1) * pageSize + 1, pageSize) .Select(i => new DataItem { Id = i, Title = $"内容项 {i}" }) .ToList(); } // 数据项模型,替换为你的业务模型 private class DataItem { public int Id { get; set; } public string Title { get; set; } = string.Empty; } }
2. 渲染滚动容器与数据列表
使用固定高度的可滚动容器包裹数据列表,并绑定滚动事件:
<div id="@_scrollContainerId" style="height: 700px; overflow-y: auto; border: 1px solid #e5e7eb;" @onscroll="HandleScroll"> @foreach (var item in _dataItems) { <div class="p-4 border-b border-gray-100"> <h3 class="font-medium">@item.Title</h3> <p class="text-gray-500 text-sm">编号:@item.Id</p> </div> } @if (_isLoading) { <div class="p-4 text-center text-gray-500"> 加载中... </div> } </div>
3. 滚动事件处理逻辑
通过Blazor内置的JSRuntime获取容器的滚动属性,判断是否到达底部并触发加载:
private async Task HandleScroll(EventArgs e) { var container = await JSRuntime.InvokeAsync<IJSObjectReference>("document.getElementById", _scrollContainerId); var scrollTop = await container.InvokeAsync<double>("getProperty", "scrollTop"); var scrollHeight = await container.InvokeAsync<double>("getProperty", "scrollHeight"); var clientHeight = await container.InvokeAsync<double>("getProperty", "clientHeight"); // 当滚动到距离底部20px以内时触发加载 if (scrollTop + clientHeight >= scrollHeight - 20 && !_isLoading) { _isLoading = true; StateHasChanged(); var newItems = await FetchPageData(++_currentPage, PageSize); if (newItems.Any()) { _dataItems.AddRange(newItems); } _isLoading = false; StateHasChanged(); } }
4. 初始化加载第一页数据
在组件初始化时加载初始的15条数据:
protected override async Task OnInitializedAsync() { _dataItems = await FetchPageData(_currentPage, PageSize); }
关键细节说明
- 这里使用
JSRuntime仅用于获取DOM元素的滚动属性,属于Blazor内置API,无需编写自定义JS脚本 _isLoading变量用于避免重复触发加载请求,防止同一时间多次调用数据接口- 可以根据需求调整滚动触发阈值(比如把20px改成更大的值,实现提前加载)
- 如果需要监听全局页面滚动,只需把滚动事件绑定到
body或window,逻辑类似
内容的提问来源于stack exchange,提问作者German Shepherd
相关产品推荐
相关产品推荐

