ios风格的时间选择插件

时间: 2018-11-17阅读: 1075标签: 插件

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


更多实现细节可以去看完整源码,以上。来源:https://www.cnblogs.com/024-faith/archive/2018/11/16/ios-timer.html


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/1358

关闭

分享 10 个超实用的 Chrome 扩展

CSSViewer这个工具在识别和显示元素的CSS属性方面很有用。它包括一个浮动窗口,您可以把鼠标悬停在页面上任一元素上以查看它的所有CSS属性。您可以通过快捷键在CSSViewer的窗体中轻松复制您选定元素的样式。

webpack插件ProvidePlugin的使用方法和eslint配置

配置 webpack.config.js文件里 plugins 属性,配置完以后就可以在代码里直接使用 _ ,而不再需要 import; 注意:(如果不配置eslint,浏览器就会报错:\\\'_\\\' is not defined no-undef)

Vue中的JS与Velocity.js的结合

JS动画效果,注意事件函数中所传递的传递的参数及某些事件函数返回的函数1.进入动画钩子:before-enter,enter,after-enter;2.离开动画钩子:before-leave,leave,after-leave;3.在enter钩子中的函数调用done

Webpack插件开发简要

如今‘大前端’这个概念在前端界大热,说‘大前端’,我们就要提到‘前后端分离’,‘前后端分离’又离不开‘本地开发构建’,‘本地开发构建’自然离不开webpack,webpack想要工作,那它就需要各种插件的支持,O(∩_∩)O哈哈~,逗了一大圈,终于引出了主题

Vue实现一个图片懒加载插件

图片懒加载是一个很常用的功能,特别是一些电商平台,这对性能优化至关重要。今天就用vue来实现一个图片懒加载的插件。 这篇博客采用“三步走”战略——Vue.use()、Vue.direction、Vue图片懒加载插件实现,逐步实现一个Vue的图片懒加载插件。

vue项目中使用新手引导功能_intro.js

如何在vue项目中使用用intro.js新手引导功能呢?这里需要使用到vue-introjs插件,vue-introjs是在Vue中绑定intro.js所使用的。在使用vue-introjs前,需要先安装intro.js

BlockUI详细用法_Jquery中ajax加载提示插件blickUI

BlockUI 插件是用于进行AJAX操作时模拟同步传输时锁定浏览器操作。当它被激活时,它会阻止使用者与页面(或页面的一部分)进行交互,直至它被取消。BlockUI以在DOM中添加元素的方法来实现阻止用户与浏览器交互的外观和行为

DefinePlugin插件用法理解

DefinePlugin 允许创建一个在编译时可以配置的全局常量。这可能会对开发模式和生产模式的构建允许不同的行为非常有用。如果在开发构建中,而不在发布构建中执行日志记录,则可以使用全局常量来决定是否记录日志。这就是 DefinePlugin 的用处

jquery.nicescroll滚动条美化插件

今天给大家介绍一个滚动条美化插件jquery.nicescroll,这个插件有以下一个主意事项:兼容所有最新的桌面浏览器和旧版:Chrome,Firefox,Edge,IE8 +,Safari(win / mac),Opera

EXIF.Js读取图片的EXIF信息

EXIF(Exchangeable Image File)是“可交换图像文件”的缩写,当中包含了专门为数码相机的照片而定制的元数据,可以记录数码照片的拍摄参数、缩略图及其他属性信息,简单来说,Exif信息是镶嵌在 JPEG/TIFF 图像文件格式内的一组拍摄参数

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!