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);
}
更多實現細節可以去看完整源碼,以上.
