为什么要封装组件

最近写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的结构如下

  1. <div class="swiper">
  2. <div class="swiper-wrapper">
  3. <div class="swiper-slide">slider1</div>
  4. <div class="swiper-slide">slider2</div>
  5. <div class="swiper-slide">slider3</div>
  6. </div>
  7. </div>

所以我们的组件分为两部分,一个外壳,一个是可重复的内容。

分别命名为SwiperTabItems.razorSwiperTabItem.razor

SwiperTabItems.razor
  1. @inject IJSRuntime JSRuntime
  2. <div class="@("swiper " + Id)">
  3. <div class="swiper-wrapper">
  4. @ChildContent
  5. </div>
  6. </div>
  7. @code{
  8. [Parameter]
  9. public int Value
  10. {
  11. get => _value;
  12. set
  13. {
  14. if (_value != value)
  15. {
  16. _value = value;
  17. if(AfterFirstRender)
  18. {
  19. UpdateSwiper(value);
  20. }
  21. }
  22. }
  23. }
  24. [Parameter]
  25. public EventCallback<int> ValueChanged { get; set; }
  26. [Parameter]
  27. public RenderFragment? ChildContent { get; set; }
  28. private int _value = 0;
  29. private bool AfterFirstRender;
  30. private string Id = "swiper" + Guid.NewGuid().ToString();
  31. protected override async Task OnAfterRenderAsync(bool firstRender)
  32. {
  33. if (firstRender && ChildContent is not null)
  34. {
  35. var dotNetCallbackRef = DotNetObjectReference.Create(this);
  36. await JSRuntime!.InvokeVoidAsync("swiperInit", new object[4] { dotNetCallbackRef, "UpdateValue", Id, Value });
  37. AfterFirstRender = true;
  38. }
  39. }
  40. private async void UpdateSwiper(int value)
  41. {
  42. await JSRuntime!.InvokeVoidAsync($"{Id}.slideTo", new object[1] { value });
  43. }
  44. [JSInvokable]
  45. public async Task UpdateValue(int value)
  46. {
  47. _value = value;
  48. if (ValueChanged.HasDelegate)
  49. {
  50. await ValueChanged.InvokeAsync(value);
  51. }
  52. StateHasChanged();
  53. }
  54. public async void Dispose()
  55. {
  56. await JSRuntime!.InvokeVoidAsync($"{Id}.destroy", new object[2] { true, true });
  57. }
  58. }
SwiperTabItem.razor
  1. <div class="swiper-slide">
  2. @ChildContent
  3. </div>
  4. @code {
  5. [Parameter]
  6. public RenderFragment? ChildContent { get; set; }
  7. }

注:

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

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

js部分

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

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

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

init-swiper.js
  1. function swiperInit(dotNetCallbackRef, callbackMethod,id,index) {
  2. console.log('Entered initSwiper!');
  3. let className = "." + id;
  4. window[id] = new Swiper(className, {
  5. observer: true,
  6. observeParents: true,
  7. observeSlideChildren: true,
  8. autoHeight: true,
  9. initialSlide: index,
  10. on: {
  11. slideChangeTransitionStart: function () {
  12. dotNetCallbackRef.invokeMethodAsync(callbackMethod, this.activeIndex);
  13. //alert(this.activeIndex);//切换结束时,告诉我现在是第几个slide
  14. },
  15. }
  16. });
  17. }

init-swiper.js引入index.html

使用

  1. <SwiperTabItems @bind-Value="tabs">
  2. <SwiperTabItem>
  3. 你的内容1
  4. </SwiperTabItem>
  5. <SwiperTabItem>
  6. 你的内容2
  7. </SwiperTabItem>
  8. <SwiperTabItem>
  9. 你的内容3
  10. </SwiperTabItem>
  11. </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. MySQL InnoDB Architecture 简要介绍

    MySQL InnoDB 存储引擎整体架构图: 一.内存存储结构 1.Buffer Pool buffer pool 是主内存中的一块儿存储区域,用于存储访问的表及索引数据.这样从内存中直接访问获取使 ...

  2. Ubuntu-管理开机自启动服务

    1. 管理服务启停工具 systemctl -- 将应用程序抽象为一个service,然后对这个service进行创建.启停.状态查看.配合journalctl进行日志管理 子命令 效果 start ...

  3. 【观察者设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    简介 观察者模式(Observer Pattern)是一种行为型模式.它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 观察者模式使用三个类S ...

  4. [C++提高编程] 3.5 stack容器

    文章目录 3.5 stack容器 3.5.1 stack 基本概念 3.5.2 stack 常用接口 3.5 stack容器 3.5.1 stack 基本概念 概念:stack是一种先进后出(Firs ...

  5. Irwin-Hall 分布学习笔记

    定理:Irwin-Hall 分布 对于 \(n\) 个在 \([0,1]\) 内均匀分布的实数随机变量,它们的和不超过一个实数 \(z\) 的概率为: \[F(z)=\sum\limits_{k=0} ...

  6. 【必知必会的MySQL知识】⑤DQL语言

    目录 一.前言 二.基础查询 2.1 语法 2.2 实践操作 三.条件查询 3.1 语法 3.2 where 语句操作符 3.3 实践操作 四.排序查询 4.1 语法格式 4.2 实践操作 五.分组查 ...

  7. 2022-06-23:给定一个非负数组,任意选择数字,使累加和最大且为7的倍数,返回最大累加和。 n比较大,10的5次方。 来自美团。3.26笔试。

    2022-06-23:给定一个非负数组,任意选择数字,使累加和最大且为7的倍数,返回最大累加和. n比较大,10的5次方. 来自美团.3.26笔试. 答案2022-06-23: 要i还是不要i,递归. ...

  8. Prompt工程师指南[从基础到进阶篇]:用于开发和优化提示,以有效地使用语言模型(LMs)进行各种应用和研究主题

    Prompt工程师指南[从基础到进阶篇]:用于开发和优化提示,以有效地使用语言模型(LMs)进行各种应用和研究主题 Prompt工程是一种相对较新的学科,用于开发和优化提示,以有效地使用语言模型(LM ...

  9. django之drf(部分讲解)

    序列化类常用字段和字段参数 drf在Django字段类型的基础上派生了自己的字段类型以及字段参数 序列化器的字段类型用于处理原始值和内部数据类型直接的转换 还可以用于验证输入.以及父对象检索和设置值 ...

  10. 这10个Lambda表达式必须掌握,简化你的代码,提高生产力

    Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名 ...