Blazor入门100天 : 自做一个手势滑动组件
####0. 我想在blazor模仿app实现触摸返回,下拉刷新 …
现在用 blazor 做 app (blazor hybird) 和支持手机浏览页面越来越多, net8 也推出了一个webapp auto模式,可谓是极大的利好, 2024 让auto流行起来, 😃
配套源码
demo https://blazor.app1.es/b20Gesture
####1. 新建 net8 blazor 工程 b20Gesture
至于用什么模式大家各取所需, 我创建的是ssr单工程, 如果大家不小心建立错了按页面渲染模式,可以在 App.razor 里面改一下, 加入 @rendermode=“RenderMode.InteractiveServer” 这句话, 默认使用ssr模式渲染.
<Routes @rendermode="RenderMode.InteractiveServer" />
####2. Components\Pages 下新建组件 GestureComponent.razor
<p>startX @startX</p>
<p>endX @endX</p>
<p>deltaX @deltaX</p>
<p>check @(Math.Abs(deltaX) > Threshold)</p>
<p>gesture @gesture</p>
<div @ontouchstart="OnTouchStart" @ontouchmove="OnTouchMove" @ontouchend="OnTouchEnd">
@ChildContent
</div>
@code {
double startX, endX, deltaX;
EnumGesture gesture = EnumGesture.None;
默认手势移动距离阈值px
[Parameter]
public int Threshold { get; set; } = 100;
[Parameter]
public RenderFragment? ChildContent { get; set; }
/// <summary>
/// 获得/设置 手势动作回调委托
/// </summary>
[Parameter]
public Func<EnumGesture, Task>? OnGesture { get; set; }
private void OnTouchStart(TouchEventArgs e)
{
// 记录手势起始点坐标
startX = e.Touches[0].PageX;
}
private void OnTouchMove(TouchEventArgs e)
{
endX = e.Touches[0].PageX;
deltaX = endX - startX;
gesture = deltaX > 0 ? EnumGesture.Right : EnumGesture.Left ;
StateHasChanged();
}
private void OnTouchEnd(TouchEventArgs e)
{
deltaX = endX - startX;
if (deltaX > 0 && deltaX > Threshold)
{
gesture = EnumGesture.Back;
}
else if (Math.Abs(deltaX) > Threshold)
{
gesture = EnumGesture.PageUp;
}
else
{
gesture = EnumGesture.None;
}
if (OnGesture != null)
{
OnGesture.Invoke(gesture);
}
StateHasChanged();
}
}
####3. 添加文件 EnumGesture.cs
using System.ComponentModel;
namespace b20Gesture.Components;
public enum EnumGesture
{
[Description("无手势")]
None,
[Description("向左滑动")]
Left,
[Description("向右滑动")]
Right,
[Description("回退手势")]
Back,
[Description("翻页手势")]
PageUp,
[Description("刷新手势")]
Refresh,
[Description("退出手势")]
Exit,
}
####4. Home.razor 加入测试代码
@page "/"
<PageTitle>Home</PageTitle>
<GestureComponent OnGesture="OnGesture">
<div style="width:100%;height:70vh;background-color:gold;">
<p>Slide me</p>
<p>page @pageNumber</p>
</div>
</GestureComponent>
@code {
int pageNumber = 1;
private Task OnGesture(EnumGesture gesture)
{
switch (gesture)
{
case EnumGesture.Back:
pageNumber--;
break;
case EnumGesture.PageUp:
pageNumber++;
break;
default:
break;
}
if (pageNumber < 1)
{
pageNumber = 1;
}
//翻页和路由参数跳转大佬们自由发挥测试
//NavigationManager.NavigateTo($"/Page{page}");
StateHasChanged();
return Task.CompletedTask;
}
}
####5. 运行, F12 模拟手机, F5刷新