今日介紹另一個特別的內建元件 Virtualize
元件虛擬化,這個效果很類似 Lazy load,只渲染使用者看得見的部分
基本使用#
以下的程式碼一次性會產出5000個 div
標籤
1
2
3
4
5
6
7
8
9
10
11
12
13
| @page "/VirtualizeExample"
<div style="height:500px;overflow-y:scroll">
@foreach (var content in contentList)
{
<div class="alert alert-primary" role="alert">
@content
</div>
}
</div>
@code {
private List<int> contentList = Enumerable.Range(0, 5000).ToList();
}
|
改寫成 Virtualize
1
2
3
4
5
6
7
8
9
10
11
12
| @page "/VirtualizeExample"
<div style="height:500px;overflow-y:scroll">
<Virtualize Items="contentList">
<div class="alert alert-primary" role="alert">
@context
</div>
</Virtualize>
</div>
@code {
private List<int> contentList = Enumerable.Range(0, 5000).ToList();
}
|
效果一樣,但是實際上是在捲動時渲染
指定資料來源#
若不想要將資料一次載入記憶體內,而想從外部提供資料我們可以設定 ItemsProvider
,Provider
會接收到ItemsProviderRequest
,告知需要跳過幾筆資料提供幾筆資料以及資料的總數,就像做分頁一樣,以下是實作 ItemsProvider
的部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| @page "/VirtualizeExample"
<div style="height:500px;overflow-y:scroll">
<Virtualize ItemsProvider="@LoadData">
<div class="alert alert-primary" role="alert">
@context
</div>
</Virtualize>
</div>
@code {
private List<int> contentList = Enumerable.Range(0, 5000).ToList();
private async ValueTask<ItemsProviderResult<int>> LoadData(ItemsProviderRequest request)
{
Console.WriteLine($"跳過 {request.StartIndex} 取得{request.Count}");
return new ItemsProviderResult<int>(contentList.Skip(request.StartIndex).Take(request.Count), contentList.Count);
}
}
|
可以在右邊的 Console 上看到,當我往下捲動 Blazor 也不斷的在幫我取得資料
預留框架#
如果資料是遠端來源,可能需要一點時間才能取得 Blazor 也有提供預留資料位置的方法,分別是 ItemContent
和 Placeholder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| @page "/VirtualizeExample"
<div style="height:500px;overflow-y:scroll">
<Virtualize ItemsProvider="@LoadData">
<ItemContent>
<div class="alert alert-primary" role="alert">
@context
</div>
</ItemContent>
<Placeholder>
<div class="alert alert-primary" role="alert">
載入中
</div>
</Placeholder>
</Virtualize>
</div>
@code {
private List<int> contentList = Enumerable.Range(0, 5000).ToList();
private async ValueTask<ItemsProviderResult<int>> LoadData(ItemsProviderRequest request)
{
await Task.Delay(TimeSpan.FromSeconds(1));
Console.WriteLine($"跳過 {request.StartIndex} 取得{request.Count}");
return new ItemsProviderResult<int>(contentList.Skip(request.StartIndex).Take(request.Count), contentList.Count);
}
}
|
以上是元件虛擬化的一些基本用法說明,明天會繼續完成內建元件的介紹