最近写MAUI Blazor的时候,总是苦于对移动端没有什么好的支持,没有一个能左右滑动的tab切换组件。
既然没有,那就自己封装一个。
简单了解轮播图、tab切换的库之后,决定使用根据Swiper来封装。
Swiper是js的插件,所以需要js与.NET互操作,有以下两点
下载Swiper,一个js文件和一个css文件,swiper-bundle.min.js
,swiper-bundle.min.css
。
最好用7的版本,8的版本会有一些兼容问题。
将文件引入index.html
如官网所示,swiper的结构如下
<div class="swiper">
<div class="swiper-wrapper">
<div class="swiper-slide">slider1</div>
<div class="swiper-slide">slider2</div>
<div class="swiper-slide">slider3</div>
</div>
</div>
所以我们的组件分为两部分,一个外壳,一个是可重复的内容。
分别命名为SwiperTabItems.razor
和SwiperTabItem.razor
@inject IJSRuntime JSRuntime
<div class="@("swiper " + Id)">
<div class="swiper-wrapper">
@ChildContent
</div>
</div>
@code{
[Parameter]
public int Value
{
get => _value;
set
{
if (_value != value)
{
_value = value;
if(AfterFirstRender)
{
UpdateSwiper(value);
}
}
}
}
[Parameter]
public EventCallback<int> ValueChanged { get; set; }
[Parameter]
public RenderFragment? ChildContent { get; set; }
private int _value = 0;
private bool AfterFirstRender;
private string Id = "swiper" + Guid.NewGuid().ToString();
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender && ChildContent is not null)
{
var dotNetCallbackRef = DotNetObjectReference.Create(this);
await JSRuntime!.InvokeVoidAsync("swiperInit", new object[4] { dotNetCallbackRef, "UpdateValue", Id, Value });
AfterFirstRender = true;
}
}
private async void UpdateSwiper(int value)
{
await JSRuntime!.InvokeVoidAsync($"{Id}.slideTo", new object[1] { value });
}
[JSInvokable]
public async Task UpdateValue(int value)
{
_value = value;
if (ValueChanged.HasDelegate)
{
await ValueChanged.InvokeAsync(value);
}
StateHasChanged();
}
public async void Dispose()
{
await JSRuntime!.InvokeVoidAsync($"{Id}.destroy", new object[2] { true, true });
}
}
<div class="swiper-slide">
@ChildContent
</div>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
注:
1.id使用guid是为了如果存在多个组件,js的实例化不会重复
2.OnAfterRenderAsync是blazor的一个生命周期,位于渲染之后,将swiper的初始化实例放在这个位置才能正确初始化。firstRender 代表第一次渲染。
如swiper官网所示,需要初始化实例
<script>
var mySwiper = new Swiper('.swiper', {
autoplay: true,//可选选项,自动滑动
})
</script>
所以我们需要写一个init-swiper.js
文件,包含初始化实例的函数,以供Blazor的调用
function swiperInit(dotNetCallbackRef, callbackMethod,id,index) {
console.log('Entered initSwiper!');
let className = "." + id;
window[id] = new Swiper(className, {
observer: true,
observeParents: true,
observeSlideChildren: true,
autoHeight: true,
initialSlide: index,
on: {
slideChangeTransitionStart: function () {
dotNetCallbackRef.invokeMethodAsync(callbackMethod, this.activeIndex);
//alert(this.activeIndex);//切换结束时,告诉我现在是第几个slide
},
}
});
}
将init-swiper.js
引入index.html
<SwiperTabItems @bind-Value="tabs">
<SwiperTabItem>
你的内容1
</SwiperTabItem>
<SwiperTabItem>
你的内容2
</SwiperTabItem>
<SwiperTabItem>
你的内容3
</SwiperTabItem>
</SwiperTabItems>
这个封装的比较简单,如果需要更多的属性,可以看看swiper的文档
手机扫一扫
移动阅读更方便
你可能感兴趣的文章