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. 洛谷 P2483 BZOJ 1975 [SDOI2010]魔法猪学院

    题目描述 iPig在假期来到了传说中的魔法猪学院,开始为期两个月的魔法猪训练.经过了一周理论知识和一周基本魔法的学习之后,iPig对猪世界的世界本原有了很多的了解:众所周知,世界是由元素构成的:元素与 ...

  2. 念念不忘SERVLET

    这个弄弄也有意思,以前无法入门,没有系统性概念,现在慢慢开始懂了.. 这个SERVLET/JSP学习笔记也易懂.. 那个JAVA7程序设计也可以慢慢看来,, 再加上SPRING,我黑心了??:) pa ...

  3. [bzoj4084][Sdoi2015]双旋转字符串_hash

    双旋转字符串 bzoj-4084 Sdoi-2015 题目大意:给定两个字符串集合 S 和 T .其中 S 中的所有字符串长度都恰好为 N ,而 T 中所有字符串长度都恰好为 M .且 N+M 恰好为 ...

  4. RONOJ——PID204 / 特种部队 ☆

    题目描述 某特种部队接到一个任务,需要潜入一个仓库.该部队士兵分为两路,第一路士兵已经在正面 牵制住了敌人,第二路士兵正在悄悄地从后方秘密潜入敌人的仓库. 当他们到达仓库时候,发现这个仓库的锁是一把很 ...

  5. 利用junit对springMVC的Controller进行测试

    本文转自http://www.tuicool.com/articles/7rMziy 平时对junit测试service/DAO层已经很熟悉不过了,如果不了解,可以猛戳这里,但是我们要测试contro ...

  6. 这是一个文字游戏?“这个工作你们部门牵头xx”

    近期集团一个部门在联系做一个网上应用平台系统.经过几次的会议沟通,这个原本就是解决取消个人银行卡收款的需求慢慢变成了一个在线销售加收款平台,因为其对销售的业务不熟悉,现有又有应用的软件,他们也感觉到主 ...

  7. hdu 1002 A + B Problem II(大正整数相加)

    代码: #include<cstdio> #include<cstring> #define Min(a,b) ((a)<(b)?(a):(b)) using names ...

  8. P1025小飞侠的游园方案

    描述 经过抽签选择,小智将军第一个进入考场. 菜虫:(身上散射出华贵(?)的光芒)欢迎你,第一位挑战者!! 小智:……(走到菜虫身后,关灯)女王陛下,虽然我们国家现在很富裕,但也请您不要浪费电来用这么 ...

  9. A - A Compatible Pair

    Problem description Nian is a monster which lives deep in the oceans. Once a year, it shows up on th ...

  10. [Codeforces]Good Bye 2017

    A - New Year and Counting Cards #pragma comment(linker, "/STACK:102400000,102400000") #inc ...