为什么要封装组件

最近写MAUI Blazor的时候,总是苦于对移动端没有什么好的支持,没有一个能左右滑动的tab切换组件。

既然没有,那就自己封装一个。

简单了解轮播图、tab切换的库之后,决定使用根据Swiper来封装。

Swiper是js的插件,所以需要js与.NET互操作,有以下两点

  • 当js中的索引变化时,调用.NET方法改变Blazor中的索引;
  • 当Blazor中的索引变化时,调用js方法改变js中的索引。

准备工作

下载Swiper,一个js文件和一个css文件,swiper-bundle.min.jsswiper-bundle.min.css

最好用7的版本,8的版本会有一些兼容问题。

将文件引入index.html

Blazor部分

如官网所示,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.razorSwiperTabItem.razor

SwiperTabItems.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 });
}
}
SwiperTabItem.razor
<div class="swiper-slide">
@ChildContent
</div> @code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}

注:

1.id使用guid是为了如果存在多个组件,js的实例化不会重复

2.OnAfterRenderAsync是blazor的一个生命周期,位于渲染之后,将swiper的初始化实例放在这个位置才能正确初始化。firstRender 代表第一次渲染。

js部分

如swiper官网所示,需要初始化实例

<script>
var mySwiper = new Swiper('.swiper', {
autoplay: true,//可选选项,自动滑动
})
</script>

所以我们需要写一个init-swiper.js文件,包含初始化实例的函数,以供Blazor的调用

init-swiper.js
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的文档

封装一个可以左右滑动的Blazor组件的更多相关文章

  1. 封装一个优雅的element ui表格组件

    现在做后台系统用vue + elementUI 的越来越多,那element ui的 el-table 组件肯定也离不开.虽然element ui的table组件很好.但是表格和分页是分离的.每次写表 ...

  2. 使用vue.js封装一个包含图片的跑马灯组件

    初衷: 学习完Vuejs后,来准备练习仿写一下老东家的门户页面,主要是为了熟悉一下常用插件的使用,比如video.js,wow.js,swiper等等:而其中涉及到一个包含图片跑马灯组件,大概长这样( ...

  3. Vue 2.x折腾记 - (17) 基于Ant Design Vue 封装一个配置式的表单组件

    前言 写了个类似上篇搜索的封装,但是要考虑的东西更多. 具体业务比展示的代码要复杂,篇幅太长就不引入了. 效果图 2019-04-25 添加了下拉多选的渲染,并搜索默认过滤文本而非值 简化了渲染的子组 ...

  4. 小程序封装一个有输入框的modal层组件

    其实很简单,就是在modal中添加新的 input <view> <modal class="modal" wx:if="{{!hiddenModal} ...

  5. Blazor组件自做五 : 使用JS隔离封装Google地图

    Blazor组件自做五: 使用JS隔离封装Google地图 运行截图 演示地址 正式开始 1. 谷歌地图API 谷歌开发文档 开始学习 Maps JavaScript API 的最简单方法是查看一个简 ...

  6. Blazor组件自做六 : 使用JS隔离封装Baidu地图

    1. 运行截图 演示地址 2. 在文件夹wwwroot/lib,添加baidu子文件夹,添加baidumap.js文件 2.1 跟上一篇类似,用代码方式异步加载API,脚本生成新的 body > ...

  7. Blazor组件自做一 : 使用JS隔离封装viewerjs库

    Viewer.js库是一个实用的js库,用于图片浏览,放大缩小翻转幻灯片播放等实用操作 本文相关参考链接 JavaScript 模块中的 JavaScript 隔离 Viewer.js工程 Blazo ...

  8. Go/Python/Erlang编程语言对比分析及示例 基于RabbitMQ.Client组件实现RabbitMQ可复用的 ConnectionPool(连接池) 封装一个基于NLog+NLog.Mongo的日志记录工具类LogUtil 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!

    Go/Python/Erlang编程语言对比分析及示例   本文主要是介绍Go,从语言对比分析的角度切入.之所以选择与Python.Erlang对比,是因为做为高级语言,它们语言特性上有较大的相似性, ...

  9. Blazor组件自做八 : 使用JS隔离封装屏幕键盘kioskboard.js组件

    1. 运行截图 演示地址 2. 在文件夹wwwroot/lib,添加kioskboard子文件夹,添加kioskboards.js文件 2.1 常规操作,懒加载js库, export function ...

  10. Blazor组件自做三 : 使用JS隔离封装ZXing扫码

    Blazor组件自做三 : 使用JS隔离封装ZXing扫码 本文基础步骤参考前两篇文章 Blazor组件自做一 : 使用JS隔离封装viewerjs库 Blazor组件自做二 : 使用JS隔离制作手写 ...

随机推荐

  1. 基于RL(Q-Learning)的迷宫寻路算法

    强化学习是一种机器学习方法,旨在通过智能体在与环境交互的过程中不断优化其行动策略来实现特定目标.与其他机器学习方法不同,强化学习涉及到智能体对环境的观测.选择行动并接收奖励或惩罚.因此,强化学习适用于 ...

  2. [MAUI]模仿网易云音乐黑胶唱片的交互实现

    @ 目录 创建页面布局 创建手势控件 创建影子控件 唱盘拨动交互 唱盘和唱针动画 项目地址 用过网易云音乐App的同学应该都比较熟悉它播放界面. 这是一个良好的交互设计,留声机的界面隐喻准确地向人们传 ...

  3. [OpenCV-Python] 21 OpenCV 中的轮廓

    文章目录 OpenCV-Python:IV OpenCV中的图像处理 21 OpenCV 中的轮廓 21.1 初识轮廓 21.1.1 什么是轮廓 21.1.2 怎样绘制轮廓 21.1.3 轮廓的近似方 ...

  4. 2022年5月5日模拟赛题解与总结(ABC237)

    总结 初一第一,竞赛班第二 还可以,为了照顾提高班来的四个同学放了四个水题,可惜他们做的不是很理想,希望他们下次可以获得满意的成绩 这次做的其实是 AtCoder ABC237 A.Not Overf ...

  5. 2022-10-16:以下go语言代码输出什么?A:timed out;B:panic;C:没有任何输出。 package main import ( “context“ “fmt“

    2022-10-16:以下go语言代码输出什么?A:timed out:B:panic:C:没有任何输出. package main import ( "context" &quo ...

  6. Stream流根据属性去重

    List根据属性去重 创建一个user集合 User user1 = new User("user1", 18, "AAA"); User user2 = ne ...

  7. Ubuntu下串口工具 PicoCOM 的使用和时间戳显示

    PICOCOM Ubuntu下的串口软件, 除了 CuteCOM, screen, MiniCOM 以外, 还有一个和 MiniCOM 很像的 PicoCOM. 最近在调试 CH340C 串口的过程中 ...

  8. pages.json 文件:自定义导航栏

    自定义导航栏使用注意 当navigationStyle设为custom或titleNView设为false时,原生导航栏不显示,此时要注意几个问题: 非H5端,手机顶部状态栏区域会被页面内容覆盖.这是 ...

  9. Django date

    date根据给定格式对一个日期变量进行格式化. 可用的格式字符串: 格式化字符 描述 示例输出a 'a.m.'或'p.m.' 'a.m.'A 'AM'或'PM' 'AM'b 月份,文字形式,3个字母, ...

  10. ps vs top:CPU占用率统计的两种不同方式

    如何计算 CPU 占用率? 简单来说,进程的 CPU 占用率指的是 CPU 有多少时间花费在了运行进程上.在 Linux 系统里,进程运行的时间是以jiffies[1]统计的,通过计算jiffies ...