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); }
更多实现细节可以去看完整源码,以上.