1.起因

  在上个项目中,客户希望时间选择插件可以是ios风格的那种,但是找了很久,发现并没有用vue的ios风格时间插件,于是自己便自己造了一个轮子.

2.插件效果

  

3.插件依赖以及安装使用

  插件依赖于better-scroll和vue,安装流程如下:

step1:  npm install vue -D
step2: npm install better-scroll -D
step3: npm install vue-ios-timer -D
step4: import vueIosTimer from 'vue-ios-timer';
step5: vue.use(vueIosTimer); 

4.源码查看与调试

  可以在我的Github上查看源码,或者已经下载过插件的同学可以在node_modules/vue-ios-timer/src/packages/timer.vue中查看,需要调试源码的同学可以将node_modules/package.json中main的value值改为src/packages/index.js,然后正常使用,其运行的代码便是node_modules/vue-ios-timer/src/packages/timer.vue中的代码.

5.实现思路

  1) 生成年,月,日,时,分,五个数组,根据插件属性type(可选值有date,datetime,time)初始化timeList二维数组,并初始化初始值;

initBasicData(){

	for(let i=1900; i<=2100; i++){
this.years.push(i+'年');
} for(let i=0; i<60; i++){
if(i>0 && i<=12){
this.monthes.push(String(i).padStart(2,'0')+'月');
}
if(i>0 && i<=31){
this.days.push(String(i).padStart(2,'0')+'日');
}
if(i<24){
this.hours.push(String(i).padStart(2,'0')+'时');
}
this.minutes.push(String(i).padStart(2,'0')+'分');
}
// 当type=date并且有默认值时
if(this.type == 'date' && this.datex){
let y = new Date(this.datex).getFullYear();
let m = new Date(this.datex).getMonth();
let d = new Date(this.datex).getDate();
this.timerSelectIndex = [y-1900, m, d-1];
// 当type=datetime并且有默认值
}else if(this.type == 'datetime' && this.datetimex){
let y = new Date(this.datetimex).getFullYear();
let m = new Date(this.datetimex).getMonth();
let d = new Date(this.datetimex).getDate();
let h = new Date(this.datetimex).getHours();
let min= new Date(this.datetimex).getMinutes();
this.timerSelectIndex = [y-1900, m, d-1, h, min];
// 当type=time并且有默认值
}else if(this.type == 'time' && this.timex){
let h = Number(this.timex.split(':')[0]);
let min= Number(this.timex.split(':')[1]);
this.timerSelectIndex = [h, min];
}else{
// 当没有默认值的时候
this.timerSelectIndex = [0,0,0,0,0];
}
},
initTimeList(){
if(this.type == 'datetime'){
this.timeList.push(this.years);
this.timeList.push(this.monthes);
this.timeList.push(this.days);
this.timeList.push(this.hours);
this.timeList.push(this.minutes);
}else if(this.type == 'time'){
this.timeList.push(this.hours);
this.timeList.push(this.minutes);
}else {
this.timeList.push(this.years);
this.timeList.push(this.monthes);
this.timeList.push(this.days);
}
},

  2) 有了基础数据,通过better-scroll初始化滚动列表,better-scroll可以开启wheel选项,实现多列表的滚动交互,而后我们每个月的天数是有可能不一样的,所以需要动态的改变日数组,改变的时机应该是当年份列表滚动或者月份列表滚动结束的时候;

initScroll(){
// 循环初始化多个列表
if(!this.$refs.timerWrapper){
return
};
let timerWrapper = this.$refs.timerWrapper; for(let i=0; i<timerWrapper.children.length; i++){ let wheel = new Bscroll(timerWrapper.children[i],{
wheel : {
rotate : 25,
selectedIndex : this.timerSelectIndex[i],
wheelWrapperClass : 'wheel-scroll',
wheelItemClass : 'wheel-item'
},
probeType : 3
});
this.wheels.push(wheel);
} // 监听scrollEnd事件,当滚动结束以后,重新渲染天这一列
this.wheels.forEach((wheel,i)=>{
wheel.on('scrollEnd',(pos)=>{
if((this.type == 'date' || this.type == 'datetime') && i != 2){
let year = 1900 + this.wheels[0].getSelectedIndex();
let month = this.wheels[1].getSelectedIndex()+1;
let newDays = this.getDays(Number(year),Number(month)); this.$set(this.timeList,2, newDays);
this.wheels[2].refresh();
}
})
})
},
getDays(year,month){
// 根据年份和月份得到当月的天数
let isLeapYear = (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
let bigMonthes = [1,3,5,7,8,10,12];
let isBigMonth = bigMonthes.indexOf(month) > -1;
let days = []; for(let i=1; i<=31; i++){
days.push(String(i).padStart(2,"0")+'日');
}; if(isBigMonth){
return days;
}else if(isLeapYear && month == 2){
return days.splice(1,29);
}else if(!isLeapYear && month == 2){
return days.splice(1,28);
}else{
return days.splice(1,30);
}
}

  3)  当用户所有的滚动操作结束以后,这时候需要通过发送getTime事件将选择结果暴露出去;

   getIndex(){
// 返回选中的值
let indexes = [],result = '';
this.wheels.forEach(wheel=>{
indexes.push(wheel.getSelectedIndex())
}); if(indexes.length == 3 || indexes.length == 5){
indexes = indexes.map((item,i)=>{
if(i==0){
item = 1900 + item;
}else if(i==1 || i==2){
item = String(item+1).padStart(2,'0');
}else{
item = String(item).padStart(2,'0');
}
return item;
})
}else{
indexes = indexes.map((item,i)=>{
item = String(item).padStart(2,'0');
return item;
})
} if(indexes.length == 2){
result = indexes.join(':');
}else if(indexes.length == 3){
result = indexes.join('-');
}else{
result = `${indexes[0]}-${indexes[1]}-${indexes[2]} ${indexes[3]}:${indexes[4]}`;
} this.showTimer = false;
this.$emit('getTime',result);
}

    更多实现细节可以去看完整源码,以上.

ios风格的时间选择插件的更多相关文章

  1. 构建 iOS 风格移动 Web 应用程序的8款开发框架

    使用 HTML5,CSS3 和 JavaScript 开发移动应用经过实践证明是一种可行的方式.这里收录了几款 iOS 风格的手机应用程序开发框架,帮助您使用擅长的 Web 技术来开发移动应用程序.这 ...

  2. 使用 iosOverlay.js 创建 iOS 风格的提示和通知

    iosOverlay.js 用于在 Web 项目中实现 iOS 风格的通知和提示效果.为了防止图标加载的时候闪烁,你需要预加载的图像资源.不兼容 CSS 动画的浏览器需要 jQuery 支持.浏览器兼 ...

  3. PhotoSwipe - 移动开发必备的 iOS 风格相册

    PhotoSwipe 是一个专门针对移动设备的图像画廊,它的灵感来自 iOS 的图片浏览器和谷歌移动端图像. PhotoSwipe 提供您的访客熟悉和直观的界面,使他们能够与您的移动网站上的图像进行交 ...

  4. JS实现IOS风格对话框 jquery / zepto

    Alert alert("这个是一个alert弹窗"); Alert 自定义参数 alert({ content: "自定义alert弹窗", btnText: ...

  5. iOS 第三方库、插件、知名博客总结

    iOS 第三方库.插件.知名博客总结 用到的组件 1.通过CocoaPods安装 项目名称 项目信息 AFNetworking 网络请求组件 FMDB 本地数据库组件 SDWebImage 多个缩略图 ...

  6. iOS风格的弹出框(alert,prompt,confirm)

    前两天,自己写了一个简单的插件,在移动端使用,不管是安卓手机还是iOS系统的手机,弹出框统一使用iOS风格的. 该弹出框是依赖于jQuery的,当然也可以将用jq写的几句代码转换为原生代码. 今天把代 ...

  7. 使用Quasar设计Material和IOS风格的响应式网站

    使用Quasar设计Material和IOS风格的响应式网站 栏目: CSS · 发布时间: 8个月前 来源: segmentfault.com   本文转载自:https://segmentfaul ...

  8. 使用jQuery开发iOS风格的页面导航菜单

    在线演示1 本地下载     申请达人,去除赞助商链接 iOS风格的操作系统和导航方式现在越来越流行,在今天的jQuery教程中,我们将介绍如何生成一个iphone风格的菜单导航. HTML代码 我们 ...

  9. bootstrap风格的multiselect插件——类似邮箱收件人样式

    在开发颗粒云邮箱的过程中,遇到了一个前端的问题,就是邮箱收件人的那个multiselect的input输入框.不仅能够多选,还要能够支持ajax搜索,把联系人搜索出来.就是类似下面的这个东西: 网上找 ...

随机推荐

  1. HDU - 1043 - Eight / POJ - 1077 - Eight

    先上题目: Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  2. eclipse jvm调优

    1.初始参数 -Xms256m-Xmx1024m 2.在eclipse.ini中加入,注意一点的是D:/soft/eclipse-jee,这个目录必须存在,启动时并不会自动目录 -verbose:gc ...

  3. UVALive3938 &quot;Ray, Pass me the dishes!&quot; 线段树动态区间最大和

    AC得相当辛苦的一道题.似乎不难,可是须要想细致, 開始的时候的错误思路----是受之前做过的区间最长连续子串影响http://blog.csdn.net/u011026968/article/det ...

  4. MFC 程序的运行流程

    CWinApp::InitApplication CMyWinApp::InitInstance CMyFrameWnd::CMyFrameWnd CFrameWnd::Create CWnd::Cr ...

  5. luogu3799 妖梦拼木棒

    题目大意 有n根木棒,现在从中选4根,想要组成一个正三角形,问有几种选法?木棒长度都<=5000. 题解 根据容斥原理,三角形两条边分别由长度相等的单根木棒组成,另一条边由两条小于该边长的木棒构 ...

  6. [AHOI 2008] 聚会

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1832 [算法] 最近公共祖先 [代码] #include<bits/stdc+ ...

  7. RabbitMQ消息队列服务

    MQ 全称为 Message Queue, 消息队列( MQ ) 是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们. 一个软件它 ...

  8. kubernetes系列

    目录: 介绍的全部可以在github上找到,链接  haoprogrammer kubernetes学习:(一).kubeadm搭建kubernetes(v1.13.1)单节点集群 kubernete ...

  9. A - Dubstep

    Problem description Vasya works as a DJ in the best Berland nightclub, and he often uses dubstep mus ...

  10. 修改Visual Studio2010的主题颜色

    第一步:打开工具->扩展管理器 第二步:搜素visual studio color theme editor 第三步:找到Visual Studio Color Theme Editor 第四步 ...