• ios风格的时间选择插件


    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);
       }

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

  • 相关阅读:
    php 加反斜杠的原因与处理办法
    python2.7 正则表达式的学习
    关于thinkhphp3.1中废弃 preg_replace /e 修饰符
    python2.7 函数的参数学习
    Laravel中Homestead添加多站点时遇到问题
    安装pywin32时,出现找不到python27注册信息的解决办法
    递归例子
    在SUSE平台启动和关闭mysql服务
    SUSE11 安装mysql
    delphi调用dll动态库
  • 原文地址:https://www.cnblogs.com/024-faith/p/ios-timer.html
Copyright © 2020-2023  润新知