并且有滑动左出左进,右出右进的效果,本文将讲解怎么在Blazor
中去通过滑动切换Tab
MASA Blazor,您也可以是其他的UI框架,这个并不影响实际的运行效果,本文案例是兼容PC和Android的,演示效果是android中执行的,在PC中执行效果依然有效(亲测)
MASA Blazor 根据 MASA Blazor安装MASA Blazor
准备工作
-
MainLayout.razor文件代码
AppBar.razor文件
@inherits LayoutComponentBase
<MApp>
<AppBar>
<div class="body">
@Body
</div>
</AppBar>
</MApp>
<style>
.body {
/*设置内容高度 需要减去导航栏的高度*/
height: calc(100vh - 48px;
max-height: calc(100vh - 48px;
}
</style>
-
创建
AppBar.razor.css
文件并且添加相关代码,以下代码是为了实现切换的时候有一个出入效果,具体代码案例来自Animista - On-Demand CSS Animations Library/*左边滑动出*/ .slide-out-left { -webkit-animation: slide-out-left 0.5s; animation: slide-out-left 0.5s; } /*右边滑动出*/ .slide-out-right { -webkit-animation: slide-out-right 0.5s; animation: slide-out-right 0.5s; } /*右边滑动进*/ .slide-in-right { -webkit-animation: slide-in-right 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940 both; animation: slide-in-right 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940 both; } /*左边滑动进*/ .slide-in-left { -webkit-animation: slide-in-left 0.5s; animation: slide-in-left 0.5s; } @-webkit-keyframes slide-out-left { 0% { -webkit-transform: translateX(0; transform: translateX(0; opacity: 1; } 100% { -webkit-transform: translateX(-1000px; transform: translateX(-1000px; opacity: 0; } } @keyframes slide-out-left { 0% { -webkit-transform: translateX(0; transform: translateX(0; opacity: 1; } 100% { -webkit-transform: translateX(-1000px; transform: translateX(-1000px; opacity: 0; } } @-webkit-keyframes slide-out-right { 0% { -webkit-transform: translateX(0; transform: translateX(0; opacity: 1; } 100% { -webkit-transform: translateX(1000px; transform: translateX(1000px; opacity: 0; } } @keyframes slide-out-right { 0% { -webkit-transform: translateX(0; transform: translateX(0; opacity: 1; } 100% { -webkit-transform: translateX(1000px; transform: translateX(1000px; opacity: 0; } } @-webkit-keyframes slide-in-left { 0% { -webkit-transform: translateX(-1000px; transform: translateX(-1000px; opacity: 0; } 100% { -webkit-transform: translateX(0; transform: translateX(0; opacity: 1; } } @keyframes slide-in-left { 0% { -webkit-transform: translateX(-1000px; transform: translateX(-1000px; opacity: 0; } 100% { -webkit-transform: translateX(0; transform: translateX(0; opacity: 1; } } @-webkit-keyframes slide-in-right { 0% { -webkit-transform: translateX(1000px; transform: translateX(1000px; opacity: 0; } 100% { -webkit-transform: translateX(0; transform: translateX(0; opacity: 1; } } @keyframes slide-in-right { 0% { -webkit-transform: translateX(1000px; transform: translateX(1000px; opacity: 0; } 100% { -webkit-transform: translateX(0; transform: translateX(0; opacity: 1; } }
-
创建
AppBar
的模型用于动态添加导航栏, 创建AppBarDto.cs
文件并添加相关代码
public class AppBarDto
{
public string Key { get; set; }
/// <summary>
/// 标题
/// </summary>
public string Title { get; init; }
/// <summary>
/// 图标
/// </summary>
public string? Icon { get; set; }
/// <summary>
/// 路由
/// </summary>
public string Href { get; init; }
public AppBarDto(string title, string href, string? icon = null
{
Title = title;
Icon = icon;
Href = href;
Key = Guid.NewGuid(.ToString("N";
}
}
- 添加相关页面,在
Pages
文件夹下,分别创建Index.razor
,Feature.razor
,Friend.razor
,PersonalCenter.razor
文件相关代码:Index.razor
@page "/"
<h3>Index</h3>
Feature.razor
@page "/feature" <h3>Feature</h3>
Friend.razor
@page "/friend" <h3>Friend</h3>
PersonalCenter.razor
@page "/personal-center" <h3>PersonalCenter</h3>
- 修改
AppBar.razor
代码<div class="@Class" @ontouchstart="TouchStart" @ontouchend="TouchEnd" @onmousedown="Mousedown" @onmouseup="Mouseup" style="height: 100%"> @ChildContent </div> @*这里也可以是其他组件的Tab,其实只是记录当前的导航的数据*@ <MTabs Centered BackgroundColor="indigo" ShowArrows="false" Value="selectModel.Key" Dark> @foreach (var i in AppBars { <MTab Value="i.Key" OnClick="(=>GoHref(i"> @if (!string.IsNullOrEmpty(i.Icon { <MIcon Dark>@i.Icon</MIcon> } @i.Title </MTab> } </MTabs>
- 创建
AppBar.razor.cs
添加以下代码public partial class AppBar { #region Inject [Inject] public required NavigationManager NavigationManager { get; set; } #endregion private readonly List<AppBarDto> AppBars = new(; [Parameter] public RenderFragment ChildContent { get; set; } private AppBarDto selectModel; private string Class { get; set; } protected override void OnInitialized( { AppBars.Add(new AppBarDto("首页", "/", "home"; AppBars.Add(new AppBarDto("好友", "/personal-center", "mdi-account-group-outline"; AppBars.Add(new AppBarDto("功能", "/feature", "mdi-wrench"; AppBars.Add(new AppBarDto("个人中心", "/personal-center", "mdi-badge-account-alert"; // 默认选择的导航标签 selectModel = AppBars[0]; base.OnInitialized(; } /// <summary> /// 导航栏跳转 /// </summary> /// <param name="appBar"></param> private void GoHref(AppBarDto appBar { // 防止重复点击 if(appBar == selectModel { return; } // 当点击导航的索引大于现在导航时启动滑动效果 if(AppBars.IndexOf(appBar > AppBars.IndexOf(selectModel { Class = "slide-out-left"; Task.Run(async ( => { // 由于特效时间为0.5s 这里是等待特效完成 await Task.Delay(450; NavigationManager.NavigateTo(selectModel.Href; Class = "slide-in-right"; _ = InvokeAsync(StateHasChanged; }; } // 当点击导航的索引小于现在导航时启动滑动效果 else if (AppBars.IndexOf(appBar < AppBars.IndexOf(selectModel { Class = "slide-out-right"; Task.Run(async ( => { // 由于特效时间为0.5s 这里是等待特效完成 await Task.Delay(450; NavigationManager.NavigateTo(selectModel.Href; Class = "slide-in-left"; _ = InvokeAsync(StateHasChanged; }; } selectModel = appBar; NavigationManager.NavigateTo(appBar.Href; } /// <summary> /// 开始X坐标 /// </summary> private double _startX; #region 移动端滑动处理 /// <summary> /// 记录开始坐标 /// </summary> /// <param name="args"></param> private void TouchStart(TouchEventArgs args { var touch = args.ChangedTouches[0]; _startX = touch.ScreenX; } private void TouchEnd(TouchEventArgs args { var touch = args.ChangedTouches[0]; Switchover((decimaltouch.ScreenX; } #endregion #region PC滑动处理 /// <summary> /// 记录开始坐标 /// </summary> /// <param name="args"></param> private void Mousedown(MouseEventArgs args { _startX = args.ScreenX; } private void Mouseup(MouseEventArgs args { Switchover((decimalargs.ScreenX; } #endregion private void Switchover(decimal screenX { var index = AppBars.IndexOf(selectModel; // 限制过度滑动 if (index == AppBars.Count || index > AppBars.Count { return; } // 设置滑动最大位限制,达到这个限制才滑动生效 var size = 200; // 需要滑动200才切换 如果开始坐标x大于 当前结束的x坐标往右边切换tab if ((decimal_startX - size > screenX { // 如果右边往左边滑动 当前索引是当前最大数量的话不需要切换 if (index == AppBars.Count - 1 { return; } selectModel = AppBars[index + 1]; Class = "slide-out-left"; Task.Run(async ( => { // 由于特效时间为0.5s 这里是等待特效完成 await Task.Delay(450; NavigationManager.NavigateTo(selectModel.Href; Class = "slide-in-right"; _ = InvokeAsync(StateHasChanged; }; } else if ((decimal_startX + size < screenX { // 如果左边往右边滑动 当前索引是0的话不需要切换 if (index == 0 { return; } selectModel = AppBars[index - 1]; Class = "slide-out-right"; Task.Run(async ( => { // 由于特效时间为0.5s 这里是等待特效完成 await Task.Delay(450; NavigationManager.NavigateTo(selectModel.Href; Class = "slide-in-left"; _ = InvokeAsync(StateHasChanged; }; } } }
运行效果:
qq交流群:737776595
微信交流群: