Blazor实现微信的Tab切换功能

是否有小伙伴在使用tab的时候想进行滑动切换Tab?

并且有滑动左出左进,右出右进的效果 ,本文将讲解怎么在Blazor中去通过滑动切换Tab

本文中的UI组件使用的是MASA Blazor,您也可以是其他的UI框架,这个并不影响实际的运行效果,本文案例是兼容PC和Android的,演示效果是android中执行的,在PC中执行效果依然有效(亲测)

首先安装MASA Blazor 根据 MASA Blazor安装MASA Blazor

 

准备工作

  • 创建 AppBar.razor文件
  • 修改MainLayout.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>

@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((decimal)touch.ScreenX);
  }

  #endregion

  #region PC滑动处理

  /// <summary>
  /// 记录开始坐标
  /// </summary>
  /// <param name="args"></param>
  private void Mousedown(MouseEventArgs args)
  {
      _startX = args.ScreenX;
  }

  private void Mouseup(MouseEventArgs args)
  {
      Switchover((decimal)args.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);
          });
      }
  }
}

运行效果:

关于Blazor实现微信的Tab切换功能的文章就介绍至此,更多相关Blazor实现微信Tab切换内容请搜索编程宝库以前的文章,希望以后支持编程宝库

1.main.js文件中添加已下代码Vue.directive('drag', {//1.指令绑定到元素上回立刻执行bind函数,只执行一次//2.每个函数中第一个参数永 ...