Blazor實(shí)現(xiàn)微信的Tab切換功能
是否有小伙伴在使用tab的時(shí)候想進(jìn)行滑動(dòng)切換Tab?
并且有滑動(dòng)左出左進(jìn),右出右進(jìn)的效果 ,本文將講解怎么在Blazor
中去通過(guò)滑動(dòng)切換Tab
本文中的UI組件使用的是MASA Blazor
,您也可以是其他的UI框架,這個(gè)并不影響實(shí)際的運(yùn)行效果,本文案例是兼容PC和Android的,演示效果是android中執(zhí)行的,在PC中執(zhí)行效果依然有效(親測(cè))
首先安裝MASA Blazor
根據(jù) MASA Blazor安裝MASA Blazor
準(zhǔn)備工作
- 創(chuàng)建
AppBar.razor
文件 - 修改
MainLayout.razor
文件代碼
@inherits LayoutComponentBase <MApp> <AppBar> <div class="body"> @Body </div> </AppBar> </MApp> <style> .body { /*設(shè)置內(nèi)容高度 需要減去導(dǎo)航欄的高度*/ height: calc(100vh - 48px); max-height: calc(100vh - 48px); } </style>
創(chuàng)建 AppBar.razor.css
文件并且添加相關(guān)代碼 ,以下代碼是為了實(shí)現(xiàn)切換的時(shí)候有一個(gè)出入效果,具體代碼案例來(lái)自Animista - On-Demand CSS Animations Library
/*左邊滑動(dòng)出*/ .slide-out-left { -webkit-animation: slide-out-left 0.5s; animation: slide-out-left 0.5s; } /*右邊滑動(dòng)出*/ .slide-out-right { -webkit-animation: slide-out-right 0.5s; animation: slide-out-right 0.5s; } /*右邊滑動(dòng)進(jìn)*/ .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; } /*左邊滑動(dòng)進(jìn)*/ .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; } }
創(chuàng)建AppBar
的模型用于動(dòng)態(tài)添加導(dǎo)航欄, 創(chuàng)建AppBarDto.cs
文件并添加相關(guān)代碼
public class AppBarDto { public string Key { get; set; } /// <summary> /// 標(biāo)題 /// </summary> public string Title { get; init; } /// <summary> /// 圖標(biāo) /// </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"); } }
添加相關(guān)頁(yè)面,在Pages
文件夾下,分別創(chuàng)建Index.razor
,Feature.razor
,Friend.razor
,PersonalCenter.razor
文件相關(guān)代碼: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,其實(shí)只是記錄當(dāng)前的導(dǎo)航的數(shù)據(jù)*@ <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>
創(chuàng)建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("首頁(yè)", "/", "home")); AppBars.Add(new AppBarDto("好友", "/personal-center", "mdi-account-group-outline")); AppBars.Add(new AppBarDto("功能", "/feature", "mdi-wrench")); AppBars.Add(new AppBarDto("個(gè)人中心", "/personal-center", "mdi-badge-account-alert")); // 默認(rèn)選擇的導(dǎo)航標(biāo)簽 selectModel = AppBars[0]; base.OnInitialized(); } /// <summary> /// 導(dǎo)航欄跳轉(zhuǎn) /// </summary> /// <param name="appBar"></param> private void GoHref(AppBarDto appBar) { // 防止重復(fù)點(diǎn)擊 if(appBar == selectModel) { return; } // 當(dāng)點(diǎn)擊導(dǎo)航的索引大于現(xiàn)在導(dǎo)航時(shí)啟動(dòng)滑動(dòng)效果 if(AppBars.IndexOf(appBar) > AppBars.IndexOf(selectModel)) { Class = "slide-out-left"; Task.Run(async () => { // 由于特效時(shí)間為0.5s 這里是等待特效完成 await Task.Delay(450); NavigationManager.NavigateTo(selectModel.Href); Class = "slide-in-right"; _ = InvokeAsync(StateHasChanged); }); } // 當(dāng)點(diǎn)擊導(dǎo)航的索引小于現(xiàn)在導(dǎo)航時(shí)啟動(dòng)滑動(dòng)效果 else if (AppBars.IndexOf(appBar) < AppBars.IndexOf(selectModel)) { Class = "slide-out-right"; Task.Run(async () => { // 由于特效時(shí)間為0.5s 這里是等待特效完成 await Task.Delay(450); NavigationManager.NavigateTo(selectModel.Href); Class = "slide-in-left"; _ = InvokeAsync(StateHasChanged); }); } selectModel = appBar; NavigationManager.NavigateTo(appBar.Href); } /// <summary> /// 開(kāi)始X坐標(biāo) /// </summary> private double _startX; #region 移動(dòng)端滑動(dòng)處理 /// <summary> /// 記錄開(kāi)始坐標(biāo) /// </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滑動(dòng)處理 /// <summary> /// 記錄開(kāi)始坐標(biāo) /// </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); // 限制過(guò)度滑動(dòng) if (index == AppBars.Count || index > AppBars.Count) { return; } // 設(shè)置滑動(dòng)最大位限制,達(dá)到這個(gè)限制才滑動(dòng)生效 var size = 200; // 需要滑動(dòng)200才切換 如果開(kāi)始坐標(biāo)x大于 當(dāng)前結(jié)束的x坐標(biāo)往右邊切換tab if ((decimal)_startX - size > screenX) { // 如果右邊往左邊滑動(dòng) 當(dāng)前索引是當(dāng)前最大數(shù)量的話不需要切換 if (index == AppBars.Count - 1) { return; } selectModel = AppBars[index + 1]; Class = "slide-out-left"; Task.Run(async () => { // 由于特效時(shí)間為0.5s 這里是等待特效完成 await Task.Delay(450); NavigationManager.NavigateTo(selectModel.Href); Class = "slide-in-right"; _ = InvokeAsync(StateHasChanged); }); } else if ((decimal)_startX + size < screenX) { // 如果左邊往右邊滑動(dòng) 當(dāng)前索引是0的話不需要切換 if (index == 0) { return; } selectModel = AppBars[index - 1]; Class = "slide-out-right"; Task.Run(async () => { // 由于特效時(shí)間為0.5s 這里是等待特效完成 await Task.Delay(450); NavigationManager.NavigateTo(selectModel.Href); Class = "slide-in-left"; _ = InvokeAsync(StateHasChanged); }); } } }
運(yùn)行效果:
到此這篇關(guān)于Blazor實(shí)現(xiàn)微信的Tab切換功能的文章就介紹到這了,更多相關(guān)Blazor實(shí)現(xiàn)微信Tab切換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript實(shí)現(xiàn)的淘寶旅行通用日歷組件用法實(shí)例
這篇文章主要介紹了javascript實(shí)現(xiàn)的淘寶旅行通用日歷組件,以實(shí)例形式分析了該日歷組件的相關(guān)設(shè)置及使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08JavaScript Scoping and Hoisting 翻譯
希望這篇文章能夠給JavaScript程序員最容易困惑的部分一些啟示。我盡力寫(xiě)的全面,以免引起更多的困惑。如果我寫(xiě)錯(cuò)了或是漏掉了某些重要的東西,請(qǐng)一定讓我知道2012-07-07js圖片閃動(dòng)特效可以控制間隔時(shí)間如幾分鐘閃動(dòng)一下
這篇文章主要介紹一個(gè)圖片閃動(dòng)特效,可以控制間隔時(shí)間如幾分鐘閃動(dòng)一下,需要的朋友不要錯(cuò)過(guò)2014-08-08面試判斷元素是否在可視區(qū)域中IntersectionObserver詳解
這篇文章主要為大家介紹了判斷元素是否在可視區(qū)域中IntersectionObserver面試詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03微信小程序?qū)崿F(xiàn)tab點(diǎn)擊切換
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)tab點(diǎn)擊切換,不滑動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07JS 調(diào)試中常見(jiàn)的報(bào)錯(cuò)問(wèn)題解決方法
下面小編就為大家?guī)?lái)一篇JS 調(diào)試中常見(jiàn)的報(bào)錯(cuò)問(wèn)題解決方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05JavaScript實(shí)現(xiàn)獲取img的原始尺寸的方法詳解
在微信小程序開(kāi)發(fā)時(shí),它的image標(biāo)簽有一個(gè)默認(rèn)高度,這樣你的圖片很可能出現(xiàn)被壓縮變形的情況,所以就需要獲取到圖片的原始尺寸對(duì)image的寬高設(shè)置,本文就來(lái)分享一下JavaScript實(shí)現(xiàn)獲取img的原始尺寸的方法吧2023-03-03