Blazor如何实现类似于微信的Tab切换?

简介: Blazor如何实现类似于微信的Tab切换?

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

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

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

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

准备工作

  1. 创建 AppBar.razor文件

  2. 修改MainLayout.razor文件代码
    ```html
    @inherits LayoutComponentBase




@Body



3. 创建 `AppBar.razor.css` 文件并且添加相关代码 ,以下代码是为了实现切换的时候有一个出入效果,具体代码案例来自[Animista - On-Demand CSS Animations Library](https://animista.net/play/entrances/slide-in-blurred)

/左边滑动出/
.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;
   }

}


4. 创建`AppBar`的模型用于动态添加导航栏, 创建`AppBarDto.cs`文件并添加相关代码

```c#
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");
    }
}
  1. 添加相关页面,在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>
  1. 修改AppBar.razor代码
    ```html

@ChildContent

@这里也可以是其他组件的Tab,其实只是记录当前的导航的数据@


@foreach (var i in AppBars)
{

@if (!string.IsNullOrEmpty(i.Icon))
{
@i.Icon
}
@i.Title

}

7. 创建`AppBar.razor.cs` 添加以下代码 
```c#    

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);
            });
        }
    }
}

运行效果:

一个热爱学习的token

目录
相关文章
|
小程序 索引
【微信小程序】实现页面tab切换效果
通过以下的方法实现tab与页面内容联动。
685 0
【微信小程序】实现页面tab切换效果
|
2月前
|
消息中间件 人工智能 Java
抖音微信爆款小游戏大全:免费休闲/竞技/益智/PHP+Java全筏开源开发
本文基于2025年最新行业数据,深入解析抖音/微信爆款小游戏的开发逻辑,重点讲解PHP+Java双引擎架构实战,涵盖技术选型、架构设计、性能优化与开源生态,提供完整开源工具链,助力开发者从理论到落地打造高留存、高并发的小游戏产品。
|
3月前
|
小程序 JavaScript API
uni-halo + 微信小程序开发实录:我的第一个作品诞生记
这篇文章介绍了使用uni-halo框架进行微信小程序开发的过程,包括选择该框架的原因、开发目标以及项目配置和部署的步骤。
168 0
uni-halo + 微信小程序开发实录:我的第一个作品诞生记
|
9月前
|
自然语言处理 搜索推荐 小程序
微信公众号接口:解锁公众号开发的无限可能
微信公众号接口是微信官方提供的API,支持开发者通过编程与公众号交互,实现自动回复、消息管理、用户管理和数据分析等功能。本文深入探讨接口的定义、类型、优势及应用场景,如智能客服、内容分发、电商闭环等,并介绍开发流程和工具,帮助运营者提升用户体验和效率。未来,随着微信生态的发展,公众号接口将带来更多机遇,如小程序融合、AI应用等。
|
6月前
|
小程序 前端开发 Android开发
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
1406 29
小程序微信分享功能如何开发?开放平台已绑定仍不能使用的问题?-优雅草卓伊凡
|
JSON 小程序 JavaScript
uni-app开发微信小程序的报错[渲染层错误]排查及解决
uni-app开发微信小程序的报错[渲染层错误]排查及解决
2980 7
|
5月前
|
监控 数据可视化 数据处理
微信养号脚本,全自动插件,AUTOJS开发版
这是一套自动化微信养号工具,包含主脚本`wechat_auto.js`与配置文件`config.json`。主脚本实现自动浏览朋友圈、随机阅读订阅号文章及搜索指定公众号三大功能,支持自定义滚动次数、阅读时长等参数。代码通过随机化操作间隔模拟真实用户行为,具备完善的错误处理和日志记录功能。配套UI模块提供可视化操作界面,可实时监控任务状态与运行日志,便于调整参数设置。控制器部分扩展了批量数据处理能力,如学生信息的增删改查操作,适用于多场景应用。下载地址:https://www.pan38.com/share.php?code=n6cPZ 提取码:8888(仅供学习参考)。
|
小程序 JavaScript 前端开发
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
2597 1
|
9月前
|
人工智能 开发框架 机器人
AstrBot:轻松将大模型接入QQ、微信等消息平台,打造多功能AI聊天机器人的开发框架,附详细教程
AstrBot 是一个开源的多平台聊天机器人及开发框架,支持多种大语言模型和消息平台,具备多轮对话、语音转文字等功能。
5341 38
AstrBot:轻松将大模型接入QQ、微信等消息平台,打造多功能AI聊天机器人的开发框架,附详细教程
|
8月前
|
人工智能 自然语言处理 小程序
技术小白如何利用DeepSeek半小时开发微信小程序?
通过通义灵码的“AI程序员”功能,即使没有编程基础也能轻松创建小程序或网页。借助DeepSeek V3和R1满血版模型,用户只需用自然语言描述需求,就能自动生成代码并优化程序。例如,一个文科生仅通过描述需求就成功开发了一款记录日常活动的微信小程序。此外,通义灵码还提供智能问答模式,帮助用户解决开发中的各种问题,极大简化了开发流程,让普通人的开发体验更加顺畅。
2566 11
技术小白如何利用DeepSeek半小时开发微信小程序?

热门文章

最新文章

下一篇
oss云网关配置