timePicker.vue日曆選擇器

zgpeterliu發表於2018-05-08
<template>
    <div class="picker-box">
        <div class="mask" @click="hideTimePicker"></div>
        <div class="picker-box-c">
            <div class="picker-header">
                <div class="picker-prev" @click="preMon"> << </div>
                <div class="picker-year">{{year}}年 {{month}}月</div>
                <div class="picker-next" @click="nextMon"> >> </div>
            </div>
            <div class="picker-content">
                <div class="picker-week">
                    <div class="picker-weekday"></div>
                    <div class="picker-weekday"></div>
                    <div class="picker-weekday"></div>
                    <div class="picker-weekday"></div>
                    <div class="picker-weekday"></div>
                    <div class="picker-weekday"></div>
                    <div class="picker-weekday"></div>
                </div>
                <div class="picker-con">
                    <div class="picker-day" v-for="pick in picker"
                        :class="{'outfocus': pick.outfocus,
                                'today': pick.showday,
                                'start': showStartEnvfun(pick.dateNum,pick.outfocus),
                                'end': showEndEnvfun(pick.dateNum,pick.outfocus),
                                'black': showBlack(pick.dateNum,pick.outfocus),
                                'half': showHalffun(pick.dateNum,pick.outfocus)}"
                        @click="checkDay(pick.dateNum,pick.outfocus)">
                        {{pick.dateNum}}
                    </div>
                </div>
            </div>
            <div class="picker-footer">
                <div class="picker-button-today"><span></span>今天</div>
                <div class="picker-button-start"><span></span>開始</div>
                <div class="picker-button-end"><span></span>結束</div>
            </div>
            <div class="confim" @click="confimDate">確定</div>
        </div>

    </div>
</template>

<script>
    export default {
        data () {
            return {
                year: '',
                month: '',
                startEnv: '', //開始日期
                endEnv: '',  //結束日期
                today: '',
                picker: []
            }
        },
        mounted () {
            let date = new Date()
            this.year = date.getFullYear()
            this.month = date.getMonth() + 1
            this.today = date.getDate()
            this.startEnv = this.getTwoDay(this.year + '-' + this.month + '-' + this.today)
            this.endEnv = this.getSixDay(this.year + '-' + this.month + '-' + this.today)

            this.createCalendar(this.year, this.month)
        },
        methods: {
            createCalendar (year, month) {
                this.picker = []
                let picks = []
                let currentMonth = ''
                if(new Date().getFullYear() == year && new Date().getMonth() + 1 == month) {
                    currentMonth = true
                } else {
                    currentMonth = false
                }
                let monthStartDate = this.getFirstDay(year, month)

                var lastMonthRestDay = new Date(year, month - 1, 0).getDate()
                //求上個月剩餘多少天顯示在本月
                for (var i = 0; i < monthStartDate; i++) {
                    picks.push({
                        dateNum: lastMonthRestDay,
                        outfocus: true
                    });
                    lastMonthRestDay--
                }

                picks = picks.reverse()

                let indexMoth = this.getMonthLen(year, month)
                //本月天數
                for (var i = 1; i <= indexMoth; i++) {
                    let showday = ''
                    if (currentMonth) {
                        if (this.today === i) {
                            showday = true;
                        } else {
                            showday = false;
                        }

                    }
                    if (currentMonth && this.today > i) {
                        picks.push({
                            dateNum: i,
                            outfocus: true,
                            showday: showday
                        });
                    } else {
                        picks.push({
                            dateNum: i,
                            outfocus: false,
                            showday: showday
                        });
                    }
                }
                let nextMonLen = 42 - picks.length
                //下月天數顯示在本月
                for (var i = 1; i <= nextMonLen; i++) {
                    picks.push({
                        dateNum: i,
                        outfocus: true
                    })
                }
                this.picker = picks
            },
            preMon () {
                if (this.year == new Date().getFullYear() && this.month <= new Date().getMonth() + 1) {
                    return;
                }
                this.month -= 1;
                if (this.month < 1) {
                    this.year -= 1;
                    this.month = 12;
                }
                this.createCalendar(this.year, this.month);
            },
            nextMon () {
                 this.month += 1;
                if (this.month > 12) {
                    this.year = parseInt(this.year) + 1;
                    this.month = 1;
                }
                this.createCalendar(this.year, this.month);
            },
            checkDay (dateNum, outfocus) {
                if(!outfocus) {
                    let check_day = this.year + '-' + this.month + '-' + dateNum;
                    if (this.dateCompare(this.endEnv, check_day) == 0) { //開始後
                        this.endEnv = check_day;
                        this.showEndEnvfun(dateNum);
                    } else if (this.dateCompare(this.endEnv, check_day) == 3) {  //點結束當天
                        this.startEnv = check_day;
                        this.showHalffun(dateNum)
                    } else if (this.dateCompare(this.startEnv, check_day) == 3) {  //點開始當天
                        this.endEnv = check_day;
                        this.showHalffun(dateNum);
                    } else if (this.dateCompare(this.startEnv, check_day) == 1) {
                        this.startEnv = check_day;
                        this.showStartEnvfun(dateNum);
                    } else if (this.dateCompare(this.startEnv, check_day) == 0 && this.dateCompare(this.endEnv, check_day) == 1) {
                        var disStartEnvLen = this.getDatePeriod(this.startEnv, check_day) - 1;
                        var disSEndEnvLen = this.getDatePeriod(this.endEnv, check_day) - 1;
                        if (disStartEnvLen > disSEndEnvLen) {
                            this.endEnv = check_day;
                            this.showEndEnvfun(dateNum);
                        } else {
                            this.startEnv = check_day;
                            this.showStartEnvfun(dateNum);
                        }
                    }
                }
            },
            //兩個日期之間間隔多少天
            getDatePeriod: function (sDate1, sDate2) {
                var aDate, oDate1, oDate2, iDays;

                aDate = sDate1.split("-");
                oDate1 = new Date(aDate[1] + '/' + aDate[2] + '/' + aDate[0]); //轉換為12-18-2016格式
                aDate = sDate2.split("-");
                oDate2 = new Date(aDate[1] + '/' + aDate[2] + '/' + aDate[0]);

                iDays = parseInt(Math.abs(oDate1 - oDate2) / 1000 / 60 / 60 / 24); //把相差的毫秒數轉換為天數
                return iDays;
            },
            //獲得每個月的天數
            getMonthLen: function (year, month) {
                let nextMonth = new Date(year, month, 1);
                nextMonth.setHours(nextMonth.getHours() - 1);
                return nextMonth.getDate();
            },
            //獲得每個月第一天星期幾   0:星期日,1:星期一
            getFirstDay: function (year, month) {
                let firstDay = new Date(year, month - 1, 1);
                return firstDay.getDay();
            },
            //獲得每個月的天數
            getMonthLen: function (year, month) {
                let nextMonth = new Date(year, month, 1);
                nextMonth.setHours(nextMonth.getHours() - 1);
                return nextMonth.getDate();
            },
            //計算距離今天的後兩天日期
            getTwoDay: function (date) {
                let result = new Date((new Date(date)).getTime() + 2 * 24 * 60 * 60 * 1000);
                return result.getFullYear() + "-" + (result.getMonth() + 1) + "-" + result.getDate();
            },
            //計算距離今天的後六天日期
            getSixDay: function (date) {
                let result = new Date((new Date(date)).getTime() + 6 * 24 * 60 * 60 * 1000);
                return result.getFullYear() + "-" + (result.getMonth() + 1) + "-" + result.getDate();
            },
            confimDate () {
                this.$store.dispatch('showTimePicker', false)
                this.$emit('confirm', this.startEnv, this.endEnv)
            },
            //比較兩日期的大小
            dateCompare (date1, date2) {

                var str1 = [];
                var str2 = [];
                str1 = date1.split('-');
                str2 = date2.split('-');
                if (parseInt(str1[0]) == parseInt(str2[0]) && parseInt(str1[1]) == parseInt(str2[1]) && parseInt(str1[2]) == parseInt(str2[2])) {
                    return 3;
                } else {
                    if (parseInt(str1[0]) > parseInt(str2[0])) {
                        return 1;
                    } else if (parseInt(str1[0]) < parseInt(str2[0])) {
                        return 0;
                    } else {
                    }
                    if (parseInt(str1[1]) > parseInt(str2[1])) {
                        return 1;
                    } else if (parseInt(str1[1]) < parseInt(str2[1])) {
                        return 0;
                    } else {
                    }
                    if (parseInt(str1[2]) > parseInt(str2[2])) {
                        return 1;
                    } else if (parseInt(str1[2]) < parseInt(str2[2])) {
                        return 0;
                    } else {
                    }
                    return 0;
                }
            },
            showStartEnvfun (dateNum, outfocus) {
                if (!outfocus) {
                    if (this.startEnv == this.year + '-' + this.month + '-' + dateNum) {
                        return true;
                    } else {
                        return false;
                    }
                }
            },
            showEndEnvfun (dateNum, outfocus) {
                if (!outfocus) {
                    if (this.endEnv == this.year + '-' + this.month + '-' + dateNum) {
                        return true;
                    } else {
                        return false;
                    }
                }
            },
            showBlack (dateNum, outfocus) {
                if (!outfocus) {
                    if (this.dateCompare(this.startEnv, this.year + '-' + this.month + '-' + dateNum) == 0 &&
                        this.dateCompare(this.year + '-' + this.month + '-' + dateNum, this.endEnv) == 0) {
                        return true;
                    } else {
                        return false;
                    }
                }
            },
            showHalffun (dateNum, outfocus) {
                if (!outfocus) {
                    if (this.startEnv == this.year + '-' + this.month + '-' + dateNum && this.endEnv == this.year + '-' + this.month + '-' + dateNum) {
                        return true;
                    } else {
                        return false;
                    }
                }
            },
            hideTimePicker () {
                this.$store.dispatch('showTimePicker', false)
            }
        },
        computed: {

        }
    }
</script>

<style lang="scss" scoped>
@import '../assets/css/function';

.picker-box {
    z-index: 100;
    font-size: 14px;
    .picker-box-c {
        position: fixed;
        background: #fff;
        width: px2rem(700px);
        height: px2rem(870px);
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        border-radius: px2rem(10px);
        z-index: 1002;
        .picker-header {
            display: flex;
            justify-content: space-between;
            height: px2rem(100px);
            line-height: px2rem(100px);
            .picker-prev,
            .picker-next {
                font-size: 10px;
                width: px2rem(200px);
                text-align: center;
            }
            .picker-year {
                color: #76D49B;
                font-weight: 700;
            }
        }
        .picker-content {
            .picker-week {
                display: flex;
                .picker-weekday {
                    width: px2rem(100px);
                    height: px2rem(60px);
                    line-height: px2rem(60px);
                    text-align: center;
                }
            }
            .picker-con {
                display: flex;
                flex-wrap: wrap;
                .picker-day {
                    position: relative;
                    width: px2rem(100px);
                    height: px2rem(80px);
                    line-height: px2rem(80px);
                    margin: px2rem(2px) 0;
                    colors: #555;
                    font-weight: 600;
                    text-align: center;
                }
                .today {
                    &::before {
                        content: " ";
                        position: absolute;
                        top: 0;
                        right: 0;
                        width: 0;
                        height: 0;
                        border-top: 8px solid #1486f5;
                        border-left: 8px solid transparent;
                    }
                }
                .start {
                    background: #5ec443;
                }
                .black {
                    background: #e2e2e2;
                }
                .end {
                    background: #d44040;
                }
                .half {
                    background: url('../assets/images/same-day.png') no-repeat;
                    background-size: cover;
                }
                .outfocus {
                    color: #e3e3e3;
                }
            }
        }
        .picker-footer {
            width: 90%;
            height: px2rem(100px);
            line-height: px2rem(100px);
            margin: 0 auto;
            display: flex;
            border-bottom: 1px solid #eee;
            >div{
                width: 33.33%;
                text-align: center;
            }
            .picker-button-today {
                span {
                    width: 0;
                    display: inline-block;
                    margin-right: px2rem(20px);
                    border-top: 8px solid #0059bc;
                    border-left: 8px solid transparent;
                }
            }
            .picker-button-start,
            .picker-button-end {
                span {
                    width: px2rem(40px);
                    height: px2rem(40px);
                    background: #5ec443;
                    display: inline-block;
                    margin-right: px2rem(20px);
                    vertical-align: middle;
                    margin-bottom: px2rem(5px);
                }
            }
            .picker-button-end {
                span {
                    background: #d44040;
                }
            }
        }
        .confim {
            width: 100%;
            height: px2rem(100px);
            line-height: px2rem(100px);
            text-align: center;
            font-size: 14px;
            color: #76D49B;
            cursor: pointer;
        }
    }
    .mask {
        position: fixed;
     width: 100%;
     margin: 0 auto;
     top: 0;
     left: 0;
     bottom: 0;
     right: 0;
     z-index: 1001;
     background: rgba(0,0,0,.6);
    }
}
</style>




com.js
import * as types from '../types'
const state = {
showTimePicker: false,
}
const actions = {
    showTimePicker({ commit }, status) {
        commit(types.COM_SHOW_TIME_PICKER, status)
    }

}
const mutations = {
[types.COM_SHOW_TIME_PICKER](state, status) {
    state.showTimePicker = status
},
}



相關文章