小程序自定义日历组件

摘要:
----˃从'@/static/js/getWeek'导出{getWeek}导出默认值{name:'calendar',props:{defaultTime:{type:String,默认值:''},//一周的第一天开始:{type:Number,默认值1},///标记的日期markDay:{type:Array,默认值()=˃{return[]}},//是否显示月份切换按钮headerBar:{type:Boolean,default:false},///是否展开打开:{type:Boolean,默认:false};//是否折叠:{type:Boolean、default:false},//是否禁用未来日期在:{type:Boolean、默认:false}之后,Data(){return{HeaderBar:false,Open:false,weektext:['day','一','二','三','四','五','六'],y:newDate().getFullYear(),//年m:newDate(().get month()+1,//月日期:“”,dates:[],//当前月份位置的日期数据Top:0,monthOpen:true,choose:“”,week:'',startDate:'',endDate:''},watch:{HeaderBar{this.HeaderBar=val},open{this.open=valthis.toggle()},Created(){thist.date=this.getToday().datethis.choose=this.defaultTime?Day:7letweek=Math.eeithis.week=weekletweekText=['Day','one','two','three','four','five','6']letformatWeek='week'+weekText[Day]lettoday={date:y+'-'+this.formatNum(m+1)+'+thist.formatNum,Day:formatWeek}re

小程序自定义日历组件第1张

根据项目需求自己封装的calendar组件

<template>
    <div class="calendar-wrapper">
        <div class="header transition" v-if="HeaderBar">
            <div class="pre" @click="changeMonth('pre')">
                <image src="/static/img/icons/icon-arrow-left.png" />
            </div>
            <div>{{ y + '年' + formatNum(m) + '月' }}</div>
            <div class="next" @click="changeMonth('next')">
                <image src="/static/img/icons/icon-arrow-right.png" />
            </div>
        </div>
        <div class="day">
            <div class="week-day" :class="{ 'text-ccc': !HeaderBar }" v-for="(item, index) in weekDay" :key="index">
                {{ item }}
            </div>
        </div>
        <div :class="{ hide: !monthOpen }" class="content" :style="{ height: height }">
            <div class="days transition" :style="{ top: positionTop + 'rpx' }">
                <div
                    class="item"
                    :class="{ week: Open && hasWeek(item), weekStart: isWeekStart(item), weekEnd: isWeekEnd(item) }"
                    v-for="(item, index) in dates"
                    :key="index"
                >
                    <div
                        class="day"
                        :class="{
                            choose: choose == `${item.year}-${item.month}-${item.date}` && item.isCurM,
                            nolm: !item.isCurM,
                            today: isToday(item.year, item.month, item.date)
                        }"
                        @click="item.isCurM && selectOne(item, $event)"
                    >
                        {{ Number(item.date) }}
                    </div>
                    <div class="markDay" v-if="isMarkDay(item.year, item.month, item.date) && item.isCurM"></div>
                </div>
            </div>
        </div>
        <!-- <image src="http://t.zoukankan.com/static/img/icons/logo.png" mode="scaleToFill" v-if="collapsible" @click="toggle"   :class="{ down: monthOpen }"></image> -->
    </div>
</template>

<script>
import { getWeek } from '@/static/js/getWeek'

export default {
    name: 'calendar',
    props: {
        defaultTime: {
            type: String,
            default: ''
        },
        // 星期几为第一天(0为星期日)
        weekstart: {
            type: Number,
            default: 1
        },
        // 标记的日期
        markDays: {
            type: Array,
            default: () => {
                return []
            }
        },
        //是否展示月份切换按钮
        headerBar: {
            type: Boolean,
            default: false
        },
        // 是否展开
        open: {
            type: Boolean,
            default: false
        },
        //是否可收缩
        collapsible: {
            type: Boolean,
            default: false
        },
        //未来日期是否不可点击
        disabledAfter: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            HeaderBar: false,
            Open: false,
            weektext: ['', '', '', '', '', '', ''],
            y: new Date().getFullYear(), //
            m: new Date().getMonth() + 1, //
            date: '',
            dates: [], // 当前月的日期数据
            positionTop: 0,
            monthOpen: true,
            choose: '',
            week: '',
            startDate: '',
            endDate: ''
        }
    },
    watch: {
        headerBar(val) {
            this.HeaderBar = val
        },
        open(val) {
            this.Open = val
            this.toggle()
        }
    },
    created() {
        this.date = this.getToday().date
        this.choose = this.defaultTime ? this.defaultTime : this.date
        this.HeaderBar = this.open
        this.Open = this.open
        this.dates = this.monthDay(this.y, this.m)
        !this.Open && this.toggle()
    },
    computed: {
        // 顶部星期栏
        weekDay() {
            return this.weektext.slice(this.weekstart).concat(this.weektext.slice(0, this.weekstart))
        },
        height() {
            return (this.dates.length / 7) * 80 + 'rpx'
        }
    },
    methods: {
        formatNum(num) {
            let res = Number(num)
            return res < 10 ? '0' + res : res
        },
        getToday() {
            let date = new Date()
            let y = date.getFullYear()
            let m = date.getMonth()
            let d = date.getDate()
            let day = new Date().getDay()
            let _day = day ? day : 7
            let week = Math.ceil((d + 6 - _day) / 7)
            this.week = week
            let weekText = ['', '', '', '', '', '', '']
            let formatWeek = '星期' + weekText[day]
            let today = {
                date: y + '-' + this.formatNum(m + 1) + '-' + this.formatNum(d),
                day: formatWeek
            }
            return today
        },
        // 获取当前月份数据
        monthDay(y, month) {
            let dates = []
            let m = Number(month)
            let firstDayOfMonth = new Date(y, m - 1, 1).getDay() || 7 // 当月第一天星期几
            let lastDateOfMonth = new Date(y, m, 0).getDate() // 当月最后一天
            let lastDayOfLastMonth = new Date(y, m - 2, 0).getDate() // 上一月的最后一天
            let weekstart = this.weekstart === 7 ? 0 : this.weekstart
            let startDay = (() => {
                // 周初有几天是上个月的
                if (firstDayOfMonth == weekstart) {
                    return 0
                } else if (firstDayOfMonth > weekstart) {
                    return firstDayOfMonth - weekstart
                } else {
                    return 7 - weekstart + firstDayOfMonth
                }
            })()
            let endDay = 7 - ((startDay + lastDateOfMonth) % 7) // 结束还有几天是下个月的
            for (let i = 1; i <= startDay; i++) {
                dates.push({
                    date: this.formatNum(lastDayOfLastMonth - startDay + i),
                    day: weekstart + i - 1 || 7,
                    month: m - 1 >= 0 ? this.formatNum(m - 1) : 12,
                    year: m - 1 >= 0 ? y : y - 1
                })
            }
            for (let j = 1; j <= lastDateOfMonth; j++) {
                dates.push({
                    date: this.formatNum(j),
                    day: (j - 1 + firstDayOfMonth) % 7 || 7,
                    month: this.formatNum(m),
                    year: y,
                    isCurM: true //是否当前月份
                })
            }
            for (let k = 1; k <= endDay; k++) {
                dates.push({
                    date: this.formatNum(k),
                    day: (lastDateOfMonth + startDay + weekstart + k - 1) % 7 || 7,
                    month: m + 1 <= 11 ? this.formatNum(m + 1) : 0,
                    year: m + 1 <= 11 ? y : y + 1
                })
            }
            return dates
        },
        // isWorkDay(y, m, d) {
        //     //是否工作日
        //     let ymd = `${y}/${m}/${d}`
        //     let formatDY = new Date(ymd.replace(/-/g, '/'))
        //     let day = formatDY.getDay()
        //     if (day == 0 || day == 6) {
        //         return false
        //     } else {
        //         return true
        //     }
        // },
        hasWeek(i) {
            const month = this.choose.split('-')[1]
            if (month === i.month) {
                let date = parseInt(i.date)
                let day = i.day
                let _day = day ? day : 7
                let week = Math.ceil((date + 6 - _day) / 7)
                Math.ceil((date + 6 - _day) / 7)
                return this.week === week
            }
        },
        isWeekStart(item) {
            const time = `${item.year}-${item.month}-${item.date}`
            return time === getWeek(this.choose).startDate
        },
        isWeekEnd(item) {
            const time = `${item.year}-${item.month}-${item.date}`
            return time === getWeek(this.choose).endDate
        },
        isFutureDay(y, m, d) {
            //是否未来日期
            let ymd = `${y}/${m}/${d}`
            let formatDY = new Date(ymd.replace(/-/g, '/'))
            let showTime = formatDY.getTime()
            let curTime = new Date().getTime()
            if (showTime > curTime) {
                return true
            } else {
                return false
            }
        },
        // 标记日期
        isMarkDay(y, m, d) {
            let flag = false
            for (let i = 0; i < this.markDays.length; i++) {
                let dy = `${y}-${m}-${d}`
                if (this.markDays[i] == dy) {
                    flag = true
                    break
                }
            }
            return flag
        },
        isToday(y, m, d) {
            let checkD = y + '-' + m + '-' + d
            let today = this.date
            if (checkD == today) {
                return true
            } else {
                return false
            }
        },
        // 展开收起
        toggle() {
            this.monthOpen = !this.monthOpen
            if (this.monthOpen) {
                this.positionTop = 0
            } else {
                let index = -1
                this.dates.forEach((i, x) => {
                    this.isToday(i.year, i.month, i.date) && (index = x)
                })
                this.positionTop = -((Math.ceil((index + 1) / 7) || 1) - 1) * 80
            }
        },
        // 点击回调
        selectOne(i) {
            let time = `${i.year}-${i.month}-${i.date}`
            let selectD = new Date(time).getTime()
            let curTime = new Date().getTime()
            let day = new Date(time).getDay()
            let date = new Date(time).getDate()
            let _day = day ? day : 7
            this.week = Math.ceil((date + 6 - _day) / 7)
            let weekText = ['', '', '', '', '', '', '']
            let formatWeek = '星期' + weekText[day]
            let response = {
                date: time,
                day: formatWeek
            }
            if (!i.isCurM) {
                // console.log('不在当前月范围内');
                return false
            }
            if (selectD > curTime) {
                if (this.disabledAfter) {
                    // console.log('未来日期不可选')
                    return false
                } else {
                    this.choose = time
                    this.$emit('onDayClick', response)
                }
            } else {
                this.choose = time
                this.$emit('onDayClick', response)
            }
            // console.log(response);
        },
        //改变年月
        changYearMonth(y, m) {
            this.dates = this.monthDay(y, m)
            this.y = y
            this.m = m
        },
        changeMonth(type) {
            if (type == 'pre') {
                if (this.m + 1 == 2) {
                    this.m = 12
                    this.y = this.y - 1
                } else {
                    this.m = this.m - 1
                }
            } else {
                if (this.m + 1 == 13) {
                    this.m = 1
                    this.y = this.y + 1
                } else {
                    this.m = this.m + 1
                }
            }
            this.dates = this.monthDay(this.y, this.m)
        }
    }
}
</script>

<style lang="scss" scoped>
.calendar-wrapper {
    color: #42464a;
    font-size: 28rpx;
    text-align: center;
    background-color: #fff;
    padding-bottom: 20rpx;

    .header {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 80rpx;
        color: #42464a;
        font-size: 32rpx;
        font-weight: bold;
        .pre,
        .next {
            font-size: 28rpx;
            font-weight: normal;
            padding: 8rpx 15rpx;
            image {
                width: 6px;
                height: 10px;
            }
        }
        .pre {
            margin-right: 30rpx;
        }
        .next {
            margin-left: 30rpx;
        }
    }

    .day {
        display: flex;
        align-items: center;
        height: 70rpx;
        line-height: 70rpx;
        border-bottom: 1rpx solid rgba(255, 255, 255, 0.2);

        .week-day {
            flex: 1;
        }
    }

    .content {
        position: relative;
        overflow: hidden;
        transition: height 0.4s ease;

        .days {
            transition: top 0.3s;
            display: flex;
            align-items: center;
            flex-wrap: wrap;
            position: relative;

            .item {
                position: relative;
                display: flex;
                align-items: center;
                justify-content: center;
                height: 80rpx;
                line-height: 80rpx;
                width: calc(100% / 7);

                .day {
                    font-style: normal;
                    display: inline-block;
                    width: 50rpx;
                    height: 50rpx;
                    line-height: 50rpx;
                    overflow: hidden;
                    border-radius: 50rpx;

                    &.choose {
                        background-color: #f5f8fb;
                    }

                    &.nolm {
                        color: #666;
                        opacity: 0.3;
                    }
                }
                /* .isWorkDay {
                    color: #42464a;
                } */
                .today {
                    /* background-color: #e4e4e4; */
                }
                .markDay {
                    position: absolute;
                    bottom: 5px;
                    width: 8rpx;
                    height: 8rpx;
                    background: #4d7df9;
                    border-radius: 10rpx;
                    font-style: normal;
                    pointer-events: none;
                }
            }
            .week {
                background-color: #f5f8fb;
            }
            .weekStart {
                border-radius: 20px 0 0 20px;
            }
            .weekEnd {
                border-radius: 0 20px 20px 0;
            }
        }
    }

    .hide {
        height: 80rpx !important;
    }

    .weektoggle {
        width: 85rpx;
        height: 32rpx;
        position: relative;
        bottom: -42rpx;
        &.down {
            transform: rotate(180deg);
            bottom: 0;
        }
    }
}
</style>

页面中调用:

<calendar ref="calendar" :defaultTime="defaultTime" :markDays="markDays" :headerBar="isHeaderBar" :open="isOpen" @onDayClick="onDayClick"></calendar>            

参考链接:https://github.com/AR1N/uniapp-calendar

免责声明:文章转载自《小程序自定义日历组件》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇2019-08-08-VMware克隆虚拟机后修改UUID、MAC地址、IP和主机名【Python】-NO.98.Note.3.Python -【Python3 解释器、运算符】下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

SpringBoot入门 (三) 日志配置

上一篇博客文章记录了在spring-boot项目中读取的属性文件中配置的属性。本文将学习如何登录springboot项目。SpringBoot在内部使用CommonsLogging进行日志记录,但它也为其他日志记录框架提供默认配置,如JavautilLogging、Log4j2和Logback。在每种情况下,日志记录器都预先配置为使用控制台输出和可选文件输出...

CSS躬行记(8)——裁剪和遮罩

裁剪最早是在CSS2.1时代由clip属性引入,但该属性只能应用于绝对定位的元素,并且只能裁剪成矩形。CSS3提供了强大的clip-path属性,突破了clip属性的众多限制,接下来将围绕clip-path属性展开讲解。3)裁剪路径对于复杂的形状,可以采用SVG来创建裁剪路径,实现自定义。2)替换元素的填充和定位CSS3引入了两个新属性,用于遮罩替换元素。...

SQLServer2008/2012 安装、添加sa用户和密码、多实例安装、修改端口, 重启生效

因为我们无法使用sa用户登录,所以只能使用系统登录。登录后,我们需要修改相关属性。右键单击数据库,然后单击属性。在这个sa的登录属性对话框中,我们首先需要设置这个用户的密码。由于此用户名是系统的用户,我们可以直接填写密码,然后再次确认密码。然后在对话框中,单击左上角的第二个属性服务器角色。这是您要实现的添加用户的角色。...

01 . 美团全链路监控CAT简介及部署

现任携程架构总监)领导基于Java开发的实时应用程序监控平台的设计。作为大众点评网的基本监控组件,AT为大众点评网业务线提供系统的性能指标、健康状态、基本警报等。如何有效定位故障并缩短故障。。。监控是运维工作中最重要的环节,吴启民也是开源实时监控系统CAT的作者。系统故障监控、业务指标监控、应用程序性能监控、用户行为监控、安全合规性监控等,如分布式监控系统C...

选包

安装系统后,将不会安装一些基本工具。此时,您可以根据yum的要求安装它们。你也可以使用任何你想要的时尚。...

Nginx实战-后端应用健康检查

utm_source=tuicool&utm_medium=referral公司前一段对业务线上的nginx做了整理,重点就是对nginx上负载均衡器的后端节点做健康检查。比如如果将max_fails设置为0,则代表不对后端服务器进行健康检查,这样还会使fail_timeout参数失效。...