Blazor实现微信的Tab切换功能

 更新时间:2023年01月23日 09:44:45   作者:token  
这篇文章主要介绍了Blazor实现微信的Tab切换功能,本文中的UI组件使用的是MASA Blazor,您也可以是其他的UI框架,这个并不影响实际的运行效果,本文案例是兼容PC和Android的,演示效果是android中执行的,在PC中执行效果依然有效,需要的朋友可以参考下

是否有小伙伴在使用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切换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JS获取屏幕高度的简单实现代码

    JS获取屏幕高度的简单实现代码

    下面小编就为大家带来一篇JS获取屏幕高度的实现代码。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05
  • javascript的indexOf忽略大小写的方法

    javascript的indexOf忽略大小写的方法

    javascript 中 indexOf 是严格区分大小写的 如何才能忽略大小写呢?
    2008-08-08
  • JavaScript实现忘记密码功能的示例代码

    JavaScript实现忘记密码功能的示例代码

    这篇文章主要为大家详细介绍了如何使用HTML、CSS和JavaScript实现一个完整的忘记密码功能,文中的示例代码讲解详细,需要的可以参考一下
    2024-01-01
  • JS中call/apply、arguments、undefined/null方法详解

    JS中call/apply、arguments、undefined/null方法详解

    这篇文章主要介绍了JS中call/apply、arguments、undefined/null方法详解的相关资料,需要的朋友可以参考下
    2016-02-02
  • js中iframe调用父页面的方法

    js中iframe调用父页面的方法

    这篇文章主要介绍了js中iframe调用父页面的方法,可通过window.parent.方法()来实现,非常具有实用价值,需要的朋友可以参考下
    2014-10-10
  • flash 得到自身url参数的代码

    flash 得到自身url参数的代码

    flash 得到自身url参数的代码,需要的朋友可以参考下。
    2009-11-11
  • js验证账户名是否重复

    js验证账户名是否重复

    这篇文章主要为大家详细介绍了js验证账户名是否重复,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • js prototype深入理解及应用实例分析

    js prototype深入理解及应用实例分析

    这篇文章主要介绍了js prototype深入理解及应用,结合实例形式分析了JavaScript prototype属性功能、原理、使用方法及操作注意事项,需要的朋友可以参考下
    2019-11-11
  • JavaScript中Array的实用操作技巧分享

    JavaScript中Array的实用操作技巧分享

    最近在调试JSP页面时频繁与ajax打交道,在复杂场景下,ajax传参数就需要对大量参数进行处理。这时我才发现,熟练Array的处理真的会使开发轻松不少!!下面就给大家分享下JavaScript中Array的实用操作技巧,有需要的可以参考借鉴。
    2016-09-09
  • JS实现页面导航与内容相互锚定实例详解

    JS实现页面导航与内容相互锚定实例详解

    这篇文章主要为大家介绍了JS实现页面导航与内容相互锚定实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10

最新评论