zoukankan      html  css  js  c++  java
  • 日期选择组件的设计

    日期选择组件是一个很常见、又挺复杂的组件,很值得好好研究一番。

    一、日期的组成

    2017-09-28 22:08:06
    年、月、日、时、分、秒

    二、日期的格式



    三、基本日期选择组件的构成


    主要由两部分构成:
    日历表格(核心)
    头部(切换月份和年份)

    四、日历模式

    日模式(基本模式)

    月模式

    年模式

    世纪模式

    五、衍生日期选择组件

    选择日期区间

    六、交互

    基本日期选择组件

    日历表格:选中某个日期、当前月份改变
    头部:上一月/下一月/上一年/下一年、切换日历模式

    日期区间选择组件

    • 开始时间和结束时间的选择在一个流程中,两次选择为一个流程,第一次选的是开始时间还是结束时间,取决于第二次选择的时间比其早还是晚。第二次选择完则时间区间确定,选择流程结束。继续选择进入下一个流程。
    • 左侧的日历表格选开始时间,右侧的表格选结束时间,可反复选择,选好点击确定按钮结束选择流程,确定时间区间。

    七、日期选择限制

    总体可选范围限制

    只能选最近一年的数据(包括今天):[-365, 0]
    只能选未来一个月的数据(包括今天):[0, 30]

    可选时间段限制

    只能选三个月的数据:90

    日期区间选择组件中选一天(小时数据)的范围限制

    只能选最近三个月(包括今天)的小时数据:[-90, 0]

    开始日期和结束日期限制的规则

    开始时间小于或等于结束时间

    八、日期选择组件的实现

    日历表格的展示(核心模块)

    • DateTable
      • DateTHead
      • DateTBody

    获取日历数组的算法(核心算法):

    输入:一个具体的日期
    输出:6X7的二维日历数组(月模式)
    例如:
    输入:2017-09-28
    输出:
    [
        [28, 29, 30, 31, 1, 2, 3],
        [4, 5, 6, 7, 8, 9, 10],
        [11, 12, 13, 14, 15, 16, 17],
        [18, 19, 20, 21, 22, 23, 24],
        [25, 26, 27, 28, 29, 30, 1],
        [2, 3, 4, 5, 6, 7, 8]
    ]
    

    在实际的实现中,数组的值一般是Date格式或者Moment格式(Moment.js库:http://momentjs.com/),方便取各种格式的日期。

    具体实现如下:

    
    import moment from 'moment';
    
    const DATE_ROW_COUNT = 6;
    
    /**
     * 获取某一周的周数组
     * @param {某个日期} date 
     * @param {第几周} num 
     * @param {数组的值的格式} format 
     */
    export function getWeekArr(date, num, format) {
        let weekArr = [];
        let dateMoment = date;
        if(!moment.isMoment(date)){
            dateMoment = moment(date);
        }
        let index = dateMoment.format('d');
        let firstDay = -index+num*7;
        let lastDay = 7-index+num*7;
        for(let day=firstDay;day<lastDay;day++){
            let weekItem = moment(dateMoment).add(day, 'days');
            let formatWeekItem = weekItem;
            if(format){
                formatWeekItem = weekItem.format(format);
            }
            weekArr.push(formatWeekItem);
        }
        return weekArr;
    }
    
    /**
     * 获取一个月的第一天
     * @param {某个日期} date 
     */
    export function getFirstDayOfMonth(date, monthNum, yearNum) {
        let dateMoment = date;
        if(!moment.isMoment(date)){
            dateMoment = moment(date);
        }
        let year = moment(dateMoment).add(yearNum, 'years').add(monthNum, 'months').format('YYYY');
        let month = moment(dateMoment).add(yearNum, 'years').add(monthNum, 'months').format('MM');
        // let month = dateMoment.format('MM');
        let day = '01';
        let firstDayOfMonth = year+'-'+month+'-'+day;
        return firstDayOfMonth;
    }
    
    /**
     * 获取日历数组
     * @param {某个日期} date 
     */
    export function getCalendarArr(date, monthNum, yearNum) {
        let calendarArr = [];
        monthNum = monthNum || 0;
        yearNum = yearNum || 0;
        let firstDayOfMonth = getFirstDayOfMonth(date, monthNum, yearNum);
        for(let row=0;row<DATE_ROW_COUNT;row++){
            let rowArr = getWeekArr(firstDayOfMonth, row);
            calendarArr.push(rowArr);
        }
        return calendarArr;
    }
    
    

    头部操作区

    日期的选择

    月份/年份的加减

    日历模式的切换

  • 相关阅读:
    软件系统的稳定性
    项目从.net 2.0 升级到。.net 4.0项目以后发现网站运行十分缓慢
    学习英语小助手(阅读粘贴的英文,使用MVVM)
    如何在IIS6,7中部署ASP.NET网站
    基于 IOCP 的通用异步 Windows Socket TCP 高性能服务端组件的设计与实现
    面向对象软件设计原则—— 软件实体的设计原则
    Django实战
    聊聊豆瓣阅读kindle版
    多线程的基本概念
    nopCommerce的源代码结构和架构
  • 原文地址:https://www.cnblogs.com/kagol/p/7608889.html
Copyright © 2011-2022 走看看