vue.js实现仿原生ios时间选择组件开发经验
前言
最近几个月一直在看VUE,然后试着只用原生js+vue实现某些组件。
PC端时间选择组件 这是最开始实现的pc上的时间选择,平时移动端也在做,所以就想实现一下移动端的时间选择器,下面分享一下我实现移动端滚轮特效时间选择器的思路和过程。整个组件是基于vue-cli来进行构建的
功能
1.时间选择[
A.年月日选择
B.年月日小时分钟选择
C.小时分钟选择 D.分钟选择]
2.滚轮效果[
A.构成一个圆环首尾相连
B.不构成首尾相连]
3.时间选择范围设置(所选时间超过范围将弹窗提示),分钟间隔设置
4.多语言设置
5.时间格式设置 满足 yyyy/MM/dd HH:mm 这一类的设置规则
6.UE上做到接近ios原生效果
7.扩展 不仅仅只能选择时间,可以传入自定义联动选择数据
这里主要讲讲无限滚轮的实现
数据准备1
这里拿
天
来做说明
获取一个月有多少天的一个巧妙的方法。
dayList () { /* get currentMonthLenght */ let currentMonthLength = new Date(this.tmpYear, this.tmpMonth + 1, 0).getDate(); /* get currentMonth day */ let daylist = Array.from({length: currentMonthLength}, (value, index) => { return index + 1 }); return daylist },
这里我用了vue 的computed方法来实现,放入
yearList
monthList
dayList
hourList
minuteList
来存储基础数据,这里数据准备就先告一段落。
静态效果实现
实现滚轮静态效果有多种方式
1.视觉3D效果[加阴影]
2.实际3D效果[CSS3D]
我把实现效果大致分为上面2种,具体的大家可以自己搜索相关资料,这里展开涉及太多就带过好了
我自己实现是用的第二种采用了CSS3D
说明
首先我们看到原生ios的选择效果在进入选择范围内和选择范围外的滚轮是有差别的
所以为了实现这个效果差别我选择用2个dom结构来实现,一个dom实现滚轮,一个dom实现黑色选中效果,这样联动的时候就有类似原生的效果差别
picker-panel
装各种选择dom,这里只给出了day的,
box-day
装天数据的一个最外层盒子,
check-line
实现选中的那2条线,
day-list
最外层黑色效果数据,
day-wheel
灰色滚轮部分
<p class="picker-panel"> <!--other box--> <p class="box-day"> <p class="check-line"></p> <p class="day-checked"> <p class="day-list"> <p class="list-p" v-for="day in renderListDay"> {{day.value}} </p> </p> </p> <p class="day-wheel"> <p class="wheel-p" v-for="day in renderListDay" transform: rotate3d(1, 0, 0, 80deg) translate3d(0px, 0px, 2.5rem);> {{day.value}} </p> </p> </p> <!--other box--> </p>
.day-wheel{ position: absolute; overflow: visible; height: px2rem(68px); font-size: px2rem(36px); top:px2rem(180px); left: 0; right: 0; color:$unchecked-date; -webkit-transform-style: preserve-3d; transform-style: preserve-3d; .wheel-p{ height: px2rem(68px); line-height: px2rem(68px); position: absolute; top:0; width: 100%; text-align: center; -webkit-backface-visibility: hidden; backface-visibility: hidden; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } }
主要涉及的css属性
transform-style: preserve-3d;
展示3D效果,
-webkit-backface-visibility: hidden;
滚轮背后部分自动隐藏
postition:absolute;
用来定位轮子
transform: rotate3d(1, 0, 0, 80deg) translate3d(0px, 0px, 2.5rem);
每个数据旋转的角度 和滚轮侧视图圆的半径
每个数据旋转的角度和构造原理
如上图
是我们滚轮的效果立体图,r 就是我们 translated3d(0px,0px,2.5rem) 这条css中的2.5rem,
如果没有这句css 那么所有的数据将汇聚在圆心
上图 不做旋转(红色代表我们看到的数据效果)
上图 做了旋转(红色 橙色代表我们看到的数据效果)
蓝色弧线表示的角度是一样的(这个涉及角的知识),也是视觉旋转角度,就是rotate3d这句css里面的80deg ,我做的是每个间隔20度,这样实际我们只用旋转x轴就顺带旋转了圆心角度,这样就把整个环给铺开了。完整一个圆可以装下360/20 个数据,而我们肉眼正能看见正面的数据,所以过了一定角度就在背后应该不能被我们看见,而-webkit-backface-visibility: hidden;这句话就起了作用。
这里我们发现轮子装不完所有数据,而且我们要实现数据循环
类似下图效果
所以就有了第二次数据准备
数据准备2
这里也是用我们的dayList作为初始数据[1,2,3,4,.....,30,31]
这里我们每次取19个数据来作为渲染数据,而我们需要renderListDay初始呈现是[23,24,25,26,27,28,29,30,31,1,2,3,4,5,6,7,8,9,10]
因为这样取最中间的数刚好是第一个(仅在初始化的时候)
renderListDay(){ let list = []; for (let k = this.spin.day.head; k <= this.spin.day.last; k++) { let obj = { value: this.getData(k, 'day'), index: k, }; list.push(obj) } return list },
取数据的方法 小于0倒着取 大于0正着取,索引大于原始数据长度都用%计算来获得正常范围对应的索引,所以上面的spin 就是我们的取数据的叉子(初始是从-9到9)
getData(idx, type){ //... else if (type == 'day') { return this.dayList[idx % this.dayList.length >= 0 ? idx % this.dayList.length : idx % this.dayList.length + this.dayList.length]; } //... },
每条数据旋转的角度(上半圆是正,下半圆是负)
<p class="wheel-p" v-for="day in renderListDay" v-bind:data-index="day.index" v-bind:style="{transform: 'rotate3d(1, 0, 0, '+ (-day.index)*20%360+'deg) translate3d(0px, 0px, 2.5rem)'}">{{day.value}}{{day.value}}</p>
接着需要旋转到我们需要的角度,跟我们的初始化时间对上,this.orDay-this.DayList[0] 是获取偏移量来矫正角度
this.$el.getElementsByClassName('day-wheel')[0].style.transform = 'rotate3d(1, 0, 0, ' + (this.orDay - this.dayList[0]) * 20 + 'deg)';
增加touch事件
剩下的事就很好处理了,给对应的dom绑定事件根据touchmove的距离来转换成旋转的角度 和check-list的位移这里translateY是用来记录实际移动的距离的,最后输出需要算入偏移量
<p class="box-day" v-on:touchstart="myTouch($event,'day')" v-on:touchmove="myMove($event,'day')" v-on:touchend="myEnd($event,'day')"> <p class="check-line"></p> <p class="day-checked"> <p class="day-list" data-translateY="0" style="transform: translateY(0rem)"> <p class="list-p" v-for="day in renderListDay" v-bind:data-index="day.index"> {{day.value}} </p> </p> </p> <p class="day-wheel" style=" transform: rotate3d(1, 0, 0,0deg)"> <p class="wheel-p" v-for="day in renderListDay" v-bind:data-index="day.index" v-bind:style="{transform: 'rotate3d(1, 0, 0, '+ (-day.index)*20%360+'deg) translate3d(0px, 0px, 2.5rem)'}"> {{day.value}} </p> </p> </p>
惯性滚动
这个实现我是用了一个 cubic-bezier(0.19, 1, 0.22, 1)
判断手势是不是flicker 如果是flicker通过一个瞬时速度来算出位移,和时间,然后一次性设置,然后用transition做惯性滚动,
普通拖动 设置1秒
这个实际效果还是有点不好,以后来改进。
其他功能的实现
这里不做详细说明了
总结
自适应方面用了手淘的解决方案
这次实现这个组件最困难的就是实现无限滚动,和无限滚动的渲染数据的构造,接着就是惯性滚动的实现。
已知问题
1.惯性滚动不完美
2.无限滚动实现了。非无限滚动没实现,就是渲染数据就是[1,2,3,4,5,6,7,8,9,10]
3.现在选择必须 年月日 或者年月日小时分钟 不能单独选小时或者分钟
以上是vue.js实现仿原生ios时间选择组件开发经验的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

一年一度的WWDC已经结束,iOS18无疑是大家关注的一大焦点。目前有许多iPhone用户都抢先升级到了iOS18,但各种系统Bug让人难受。有博主表示,升级iOS18要谨慎,因为“Bug多到飞起”。博主表示,如果你的iPhone是主力机,建议不要升级iOS18,因为第一版本的Bug非常多。他还汇总了几个目前遇到的系统Bug:1、切换图标样式卡顿,导致图标不显示2、手电筒示宽动画经常丢失3、抖音App上传不了视频4、微信消息延迟10s左右推送5、电话偶尔打不出去,显示黑屏6、发热严

感谢网友吉茵珂丝、xxx_x、番茄炒西红柿、Terrence、香辣鸡腿堡的线索投递! 7月27日消息,苹果公司今天面向开发者,重新发布了iOS/iPadOS18Beta4更新,内部版本号从22A5316j升级到22A5316k,目前尚不清楚两个Beta4版本更新之间的区别。已经注册的开发者可以打开“设置”应用程序,进入“软件更新”部分,点击“测试版更新”选项,然后切换iOS18/iPadOS18开发者测试版设置来选择测试版。下载并安装测试版需要与开发者账户关联的AppleID。 7月24日报道,iO

7月31日消息,苹果公司昨日(7月30日)发布新闻稿,宣布推出新的开源Swift包(swift-homomorphic-encryption),用于在Swift编程语言中启用同态加密。注:同态加密(HomomorphicEncryption,HE)是指满足密文同态运算性质的加密算法,即数据经过同态加密之后,对密文进行特定的计算,得到的密文计算结果在进行对应的同态解密后的明文等同于对明文数据直接进行相同的计算,实现数据的“可算不可见”。同态加密技术可以计算加密数据,而且不会向操作过程泄露底层的未加

更新:Saunders Tech 已将教程上传到他的 YouTube 频道(下面嵌入视频),解释如何在欧盟境外的 iPad 上安装 Fortnite 和 Epic Games Store。然而,该过程不仅需要特定的 iO 测试版

感谢网友香辣鸡腿堡、软媒新友2092483、手写的从前、DingHao、小星_14、窝窝头吃大口、非影Q、软媒新友2168428、Slades、Aaron212、快乐小刺猬、小伯爵、吃鱼的小奶猫的线索投递!【点此直达升级教程】7月24日消息,苹果今日向iPhone和iPad用户推送了iOS/iPadOS18开发者预览版Beta4更新(内部版本号:22A5316j),本次更新距离上次发布隔了15天。Carplay壁纸苹果为CarPlay添加了壁纸,涵盖浅色和深色两种模式,其壁纸风格类似于iPhon

在刚刚结束的欧洲杯决赛中,你是否为自己支持的球队疯狂打call?在马上到来的巴黎奥运会中,你是否也期待能完美捕捉到各赛事的高光时刻?这其中,拥有一台优质的观赛设备至关重要。哈趣K2投影仪以其高性价比和出色的性能,当之无愧地成为观赛良选。它不仅具备高亮度、清晰的画质,还能提供沉浸式的观影体验,让每一场比赛的精彩瞬间都仿佛近在咫尺。这样的设备,你是否已经心动了呢?它定能让你在家中也能享受到奥运赛事的激情与梦想。哈趣K2贴心最大的亮点就是它210°的超大角度调节,无论是天花板还是墙壁,都可以便利观影。

感谢网友末6_、嗯嗯嗯哼哼、吃猫的咸鱼、瑶池青莲、香辣鸡腿堡、思燕、蒂姆Apple的线索投递!7月30日消息,苹果今日面向iPhone和iPad用户推出了iOS18和iPadOS18公测版Beta2版本更新,距离上个公测版本过了两周时间。该公测版的更新内容类似开发者预览版Beta4,新增CarPlay壁纸、梳理设置选项、增强相机控制、深色/浅色模式图标等,具体可以看此前详细报道内容。##如何升级iOS/iPadOS/watchOS/macOS开发版和公测版?iOS/iPadOS升级iOS/iPa

苹果公司最新发布的iOS18、iPadOS18以及macOSSequoia系统为Photos应用增添了一项重要功能,旨在帮助用户轻松恢复因各种原因丢失或损坏的照片和视频。这项新功能在Photos应用的"工具"部分引入了一个名为"已恢复"的相册,当用户设备中存在未纳入其照片库的图片或视频时,该相册将自动显示。"已恢复"相册的出现为因数据库损坏、相机应用未正确保存至照片库或第三方应用管理照片库时照片和视频丢失提供了解决方案。用户只需简单几步
