vue 日历签到组件

vue写好的组件,直接安装npm install vue-checkin --save,github地址  GitHub - hasbug/vue-checkin

或者自己写,如下

新建vue-checkin.vue,里面写

<template>

    <div class="content-page uk-body">

        <div class="calendar">

            <button class="month-less" @click="prevMonth"> &lt; </button>

            <h4>{{year}}年{{month}}月</h4>

            <button class="month-add" @click="nextMonth"> &gt; </button>

            <table class="sign_tab" border="0px" cellpadding="0px" cellspacing="0px">

                <thead>

                <tr>

                    <th>日</th>

                    <th>一</th>

                    <th>二</th>

                    <th>三</th>

                    <th>四</th>

                    <th>五</th>

                    <th>六</th>

                </tr>

                </thead>

                <tbody>

                <tr v-for="(item,index) in dateArr" :key="index">

                    <template v-if="contains(item)">

                      <template  v-for="(data,index) in item">

                        <!-- 6行7列的每个单元格的date是否在签到数组里 -->

                        <td :class="{'disa':monthClass(data.month), 'cur_day': doCheck(data.date),'check_day': isCheck(data.date) }" v-if="isCheck(data.date)"  :key="index">

                            <!--<span :class="{'ui-state-up': true }">已签到</span>-->

                            <template v-if="doCheck(data.date)">

                                今天

                            </template>

                            <template v-else>

                            {{data.date | getCD}}

                            </template>

                            <span :class="{'ui-state-down': true }">金币+{{getGold(data.date)}}</span>

                        </td>

                        <!-- 如果不在签到数组里,是今天,没签到 -->

                        <template v-if="(!isCheck(data.date) && (doCheck(data.date) && !hasCheckin))">

                            <!-- 是否是当月,如果是当月显示今天,如果不是当月显示日期 -->

                            <td v-if="!monthClass(data.month)"  @click="checkNow" :class="{'disa':monthClass(data.month), 'over':data.date == '', 'cur_day': doCheck(data.date) }" :key="index">

                                今天

                                <span :class="{'ui-state-default': true }">点击签到</span>

                            </td>

                            <td v-else :class="{'disa':monthClass(data.month), 'over':data.date == '', 'cur_day': doCheck(data.date) }"  :key="index">

                                {{data.date | getCD}}

                            </td>

                        </template>

                        <!-- 没签到,不是今天,显示日期 -->

                        <td v-if="!isCheck(data.date) && (!doCheck(data.date)) "  :class="{'disa':monthClass(data.month), 'over':data.date == '', 'cur_day': doCheck(data.date) }" :key="index">

                            {{data.date | getCD}}

                        </td>

                   

                       

                      </template>

                    </template>

                   

                </tr>

                </tbody>

            </table>

        </div>

    </div>

</template>

<script>

    export default {

        name:'vueCheckin',

        data() {

            return {

                today : new Date(),

                year : '',

                month : '',

                day : '',

                date : '',

                startTime:'',

                endTime:'',

                dateArr: [],//6行7列的年月日和是否是当月的数据

                hasCheckin:false,

            };

        },

        props:['checkin'],

        created() {

            this.year = this.today.getFullYear();

            this.month = this.today.getMonth() + 1;

            this.day = this.today.getDay();

            this.date = this.today.getDate();

            this.getCalendar();

            console.log(this.checkin)

        },

        filters: {

            getCD (val){

                return val.split('/')[2]

            }

        },

        // computed:{

        //     con() {

        //         return this.

        //     }

        // },

        watch: {

            dateArr: {

                deep: true,

                handler: function (val) {

                    console.log(val)

                    this.startTime = val[0][0].date;

                    this.endTime = val[5][6].date;

                    this.setMonth(this.year+'/'+this.month,[this.startTime, this.endTime]);

                }

            }

        },

        methods: {

            //签到

            checkNow() {

                this.$emit('checkIn')

            },

            setMonth (date,){

                this.$emit('setMonth',date,[this.startTime, this.endTime])

            },

            monthClass(type) {

                if(type!='cur'){

                    return true

                }else{

                    return false

                }

            },

            getGold (thisDay) {

                for(let i in this.checkin) {

                    var d=new Date(this.checkin[i].time.replace(/-/g, '/'));

                    var _ymd = d.getFullYear()+'/'+(d.getMonth()+1)+'/'+d.getDate();

                    if(new Date(thisDay).getTime() == new Date(_ymd).getTime()) {

                        return this.checkin[i].amount;

                    }

                }

            },

            //是否是闰年

            isLeap() {

                const year = this.year;

                if(year % 4 == 0 && year % 100 > 0) {

                    return true;

                }else if(year % 400 == 0 && year % 3200 > 0) {

                    return true;

                }else {

                    return false;

                }

            },

            //单个月的天数

            getLen(m) {

                const month = m || this.month;

                if(month == 2) {

                    if(this.isLeap) {

                        return 29;

                    }else {

                        return 28;

                    }

                }else {

                    if(month < 8) {

                        if(month % 2 > 0) {

                            return 31;

                        }else {

                            return 30;

                        }

                    }else {

                        if(month % 2 > 0) {

                            return 30;

                        }else {

                            return 31;

                        }

                    }

                }

            },

            //格式化年月日

            getCalendarTime() {

                return this.year + '-' + this.month + '-' + this.date;

            },

            //得到6行7列的每个单元格的年月日和当月前一个月后一个月

            getCalendar() {

                var len = this.getLen();

                var d = new Date(this.year, this.month - 1, 1);

                var dfw = d.getDay();

                var arr = new Array();

                var tem = 0;

                var nextTem=1;

                var pre=dfw-1


 

                var _lastLen=this.getLen(this.month-1)




 

                for (var i = 0; i < 6; i++) {

                    arr[i] = new Array();

                    for (var j = 0; j < 7; j++) {

                        tem++;

                        if (tem - dfw > 0 && tem - dfw <= len) {

                            arr[i][j] = {date:this.year+'/'+(this.month)+'/'+(tem - dfw),month:'cur'};

                        } else {

                            if(tem <= dfw){

                                arr[i][j] = {date:this.year+'/'+(this.month-1)+'/'+(_lastLen-pre), month:'pre'};

                                pre--;

                            }else{

                                arr[i][j] ={date:  this.year+'/'+(this.month+1)+'/'+(nextTem), month: 'next'};

                                nextTem++

                            }

                        }

                    }

                }

                this.dateArr = arr;

                // console.log(this.dateArr);

            },

            nextMonth() {

                if(this.month == 12) {

                    this.year ++;

                    this.month = 1;

                }else {

                    this.month ++;

                }

                this.getCalendar();

            },

            prevMonth() {

                if(this.month == 1) {

                    this.year --;

                    this.month = 12;

                }else {

                    this.month --;

                }

                this.getCalendar();

            },

            //如果dataArr的某一个单元格里没有数据

            contains(arr) {

                if((arr[0] == '') && (arr[1] == '') && (arr[2] == '') && (arr[3] == '') && (arr[4] == '') && (arr[5] == '') && (arr[6] == '')) {

                    return false;

                }else {

                    return true;

                }

            },

            //是否已签到

            isCheck(index) {

                for(let i in this.checkin) {

                    var todayDate=new Date();

                    var today = todayDate.getFullYear()+'/'+(todayDate.getMonth()+1)+'/'+todayDate.getDate();

                    var d=new Date(this.checkin[i].time.replace(/-/g, '/'));

                    var _ymd = d.getFullYear()+'/'+(d.getMonth()+1)+'/'+d.getDate();

                    if(new Date(today).getTime()==new Date(_ymd).getTime()){

                        //今日已经签到

                        this.hasCheckin = true;

                    }

                    if(new Date(index).getTime() == new Date(_ymd).getTime()) {

                        // console.log('已经签到')

                        return true;

                    }

                }

                return false;

            },

            //是否是今天

            doCheck (d){

                var dString= new Date().getFullYear()+'/'+(new Date().getMonth()+1)+'/'+new Date().getDate();

                if(new Date(d).getTime() == new Date(dString).getTime()){

                    return true;

                }

                return false;

            }

        }

    };

</script>

<style  rel="stylesheet/scss" lang="scss">

    .calendar{width:100%;margin:0px 0px 20px 0px;color:#555;position: relative;}

    .calendar h4 {

        line-height: 40px;

        background-color: #fff;

        text-align: center;

        color: #333;

        box-shadow: 0 0 4px #bbb;

        -webkit-box-shadow: 0 0 4px #bbb;

    }

    .calendar button {

        position: absolute;

        width: 30px;

        height: 30px;

        top: 5px;

        color:#777;

        background: #f3f3f3;

        border: none;

    }

    .calendar button:focus { border: none;outline: none; }

    .calendar button.month-less {left: 10px;}

    .calendar button.month-add {right: 10px;}

    .calendar .sign_tab{width: 100%;border-collapse: collapse;border: 1px solid #e8e8e8;border-top: 0;table-layout: fixed;}

    .calendar .sign_tab th{text-align: center;height: 14.28571428571429vw;font-weight: 700;}

    .calendar .sign_tab td{position: relative; border: 1px solid #eee;padding: 15px 0;text-align: center;font-size: 14px;font-family: arial;}

    .calendar .sign_tab td.over{background-color: #fff;border-left: 0;border-right: 0;}

    .calendar .sign_tab td.disa{

        color:#ccc !important;

        background: none !important;

        *{

            color:#ccc !important;

        }

    }

    .calendar .sign_tab td.check_day{

        background-color: #f8f8f8;

        color: #58ce7a;

        position: relative;

    }

    .calendar{

        .ui-state-down,

        .ui-state-default{

            font-size:10px;

            width: 100%;

            text-align: center;

            position: absolute;

            bottom: 3px;

            left: 0;

        }

        .ui-state-down{

            color: #f60;

        }

    }

    .calendar  .ui-state-up{

        font-size:10px;

        width: 100%;

        text-align: center;

        position: absolute;

        top: 3px;

        left: 0;

    }

    .calendar .sign_tab td.cur_day{background-color: #FFD2D2;color: #FFF;}

    .checkin-btn{

        display: block;

        width:90%;

        margin:0 auto;

        text-align: center;

        font-size: 10px;

    }

    .tdbox{

        display:flex;

    }

</style>

在引用页面rili.vue,写

<template>

    <div>

        <vue-checkin :checkin="checkInData" @checkIn="checkIn" @setMonth="getCheckInData"></vue-checkin>

    </div>

</template>

<script>

import vueCheckin from '../../components/vue-checkin.vue'

export default {

    name: 'Lianxi6Rili',

    components: {

        vueCheckin

    },

    data() {

        return {

            checkInData:[

                {

                    "time": "2022-11-12 08:52",  //日期可以直接用2018/01/12 08:52这种正规格式,避免ios解析【-】分割的出问题

                    "amount": 3 //所得金币

                },

                {

                    "time": "2022-10-07 08:52",

                    "amount": 10

                },

                {

                    "time": "2022-11-06 08:46",

                    "amount": 6

                },

                {

                    "time": "2022-11-05 09:51",

                    "amount": 3

                }

            ]

        };

    },

    mounted() {

       

    },

    methods: {

        checkIn() {

        },

        getCheckInData() {

        }

    },

};

</script>

<style lang="scss" scoped>

</style>

大体流程是

遍历6,得到6行,遍历7,得到7列,得到当月1号是星期几,减1就是上月的在当月显示天数,事先得到每个月的天数,计数器tem每次遍历加1,如果tem<上月的在当月显示的天数,就是上个月,得到上个月的天数,当月表格的第一天是上个月的天数-(上月的在当月显示的天数-tem-1),同理得到下个月在当月显示的天数与日期。

点击签到,向后端发送现在的年月日,出现在从后端取得的已签到数组中,遍历已签到数组,看当前月的遍历的单元的毫秒数与已签到数组的哪一项的日期的毫秒数相同,已签到

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值