日历插件

适用于vue、uniapp、微信小程序的日历插件(代码片段)

原文链接:日历插件

插件说明:

适用于vue、uniapp。可运行再pc、手机浏览器、手机微信浏览器、手机app。

最近公司开发约课系统,要求日历上能展示还剩多少人可预约。我想着百度一搜一大把啊,于是我找了一上午没找到合适的,于是我结合百度的和自己的需求写了一个。

效果:


样式啥的,完全可控,还能增加状态

开始:

html:

<div class="calendar">

    <div class='tit flex_c_c'>

        <div class='pre flex_c_c' @click='gotoPreMonth()'> < </div>

        <div class='current flex_c_c'>{{currentYear}}年{{currentMonth}}月</div>

        <div class='next flex_c_c' @click='gotoNextMonth()'> > </div>

    </div>

    <div class='content1'>

        <div class="head">

            <div class="list">日</div>

            <div class="list">一</div>

            <div class="list">二</div>

            <div class="list">三</div>

            <div class="list">四</div>

            <div class="list">五</div>

            <div class="list">六</div>

        </div>

        <div class="list" v-for="(item,index) in allArr" :key="index">

            <div

                v-if="item.state==1"

                class="box succese"

            >

                <div>{{item.date}}</div>

                <div class="t24">剩{{item.num}}人</div>

            </div>

            <div

                v-else-if="item.num>0"

                :class="'box have ' + (clickDate==item.date?'clickDate':'')"

                @click="rlChange(item.date)"

            >

                <div>{{item.date}}</div>

                <div class="t24">剩{{item.num}}人</div>

            </div>

            <div

                v-else-if="item.num==0"

                class="box nothing"

            >

                <div>{{item.date}}</div>

                <div class="t24">剩{{item.num}}人</div>

            </div>

            <div

                v-else

                class="box gray"

            >

                <div>{{item.date}}</div>

            </div>

        </div>

    </div>

</div>

html根据需求还需要修改,后面细说怎么根据需求修改

css:

// 日历less写法

.calendar{

width: 100%;

    background: #fff;

    border-radius: 8rpx;

    box-shadow: 0 0 2px rgb(0 0 0 / 10%);

    .tit{

        font-size: 34rpx;

        color: #2A2A2A;

        padding: 25rpx 0;

        border-bottom: 1px solid #c8c7cc;

        .current{

            margin: 0 25rpx;

            line-height: 1;

        }

        .next{

            line-height: 1;

        }

        .pre{

            line-height: 1;

            transform:rotate(180deg);

            -ms-transform:rotate(180deg); /* IE 9 */

            -moz-transform:rotate(180deg); /* Firefox */

            -webkit-transform:rotate(180deg); /* Safari 和 Chrome */

            -o-transform:rotate(180deg); /* Opera */

        }

    }

    .content1{

        display: flex;

        flex-wrap: wrap;

        box-sizing: border-box;

        .head{

            width: 100%;

            display: flex;

            flex-wrap: wrap;

            border-bottom: 1px solid #F5F5F5;

            .list{

                background: #fff;

            }

        }

        .list{

            width: calc(14.285% - 4px);

            background: #f6f6f6;

            height: 80rpx;

            line-height: 1.2;

            display: flex;

            flex-direction: column;

            justify-content: center;

            align-items: center;

            text-align: center;

            flex-shrink: 0;

            font-size: 32rpx;

            /* background: rgb(224, 199, 199); */

            margin: 2px;

            .box{

                font-size: 28rpx;

                width: 100%;

                height: 100%;

                display: flex;

                flex-direction: column;

                justify-content: center;

                align-items: center;

                text-align: center;

            }

            .have{

                background: #fff;

            }

            .succese{

                background: #0acf63;

            }

            .nothing{

                opacity: 0.6;

            }

            .t24{

                color: #f67a47;

            }

            .clickDate{

                background: #007aff;

                color: #fff;

            }

        }

        .gray{

            color: rgba(0,0,0,0.4);

        }

    }

}

先上一段不需要修改的js吧,这段代码我是用mixin导入到页面,当然也可以写成组件,这里我只讨论方法

const calendar = {

    data () {

        return {

            clickDate: '',

            currentYear: '',

            currentMonth: '',

            currentMonthDateLen: 0, // 当月天数

            preMonthDateLen: 0, // 当月中,上月多余天数

            allArr:[], // 当月所有数据

        }

    },

    onShow() {

        var date = new Date();

        this.currentYear = date .getFullYear();

        this.currentMonth = date .getMonth()+1;

    },

    methods: {

        // 获取某年某月总共多少天

        getDateLen(year, month) {

            let actualMonth = month - 1;

            let timeDistance = +new Date(year, month) - +new Date(year, actualMonth);

            return timeDistance / (1000 * 60 * 60 * 24);

        },

        // 获取某月1号是周几

        getFirstDateWeek(year, month) {

            return new Date(year, month - 1, 1).getDay()

        },

        // 上月 年、月

        preMonth(year, month) {

            if (month == 1) {

                return {

                    year: --year,

                    month: 12

                }

            } else {

                return {

                    year: year,

                    month: --month

                }

            }

        },

        // 下月 年、月

        nextMonth(year, month) {

            if (month == 12) {

                return {

                    year: ++year,

                    month: 1

                }

            } else {

                return {

                    year: year,

                    month: ++month

                }

            }

        },

        // 获取当月中,上月多余数据,返回数组

        getPreArr(){

            let preMonthDateLen = this.getFirstDateWeek(this.currentYear, this.currentMonth) // 当月1号是周几 == 上月残余天数)

            let preMonthDateArr = [] // 定义空数组

            if (preMonthDateLen > 0) {

                let { year, month } = this.preMonth(this.currentYear, this.currentMonth) // 获取上月 年、月

                let date = this.getDateLen(year, month) // 获取上月天数

                for (let i = 0; i < preMonthDateLen; i++) {

                    preMonthDateArr.unshift({ // 尾部追加

                        month: 'pre', // 只是为了增加标识,区分当、下月

                        date: date

                    })

                    date--

                }

            }

            this.preMonthDateLen=preMonthDateLen

            return preMonthDateArr

        },

        // 获取当月中,下月多余数据,返回数组

        getNextArr() {

            let nextMonthDateLen = 42 - this.preMonthDateLen - this.currentMonthDateLen // 下月多余天数

            let nextMonthDateArr = [] // 定义空数组

            if (nextMonthDateLen > 0) {

                for (let i = 1; i <= nextMonthDateLen; i++) {

                    nextMonthDateArr.push({

                        month: 'next',// 只是为了增加标识,区分当、上月

                        date: i

                    })

                }

            }

            return nextMonthDateArr

        },

        // 整合当月所有数据

        getAllArr(currentMonthDateArr){

            let preArr = this.getPreArr()

            let currentArr = currentMonthDateArr

            let nextArr = this.getNextArr()

            let allArr = [...preArr, ...currentArr, ...nextArr]

            this.allArr=allArr

        },

        // 点击 上月

        gotoPreMonth(){

            this.clickDate = ''

            let { year, month } = this.preMonth(this.currentYear, this.currentMonth)

            this.currentYear= year,

            this.currentMonth= month

            this.getCurrentArr()

        },

        // 点击 下月

        gotoNextMonth() {

            this.clickDate = ''

            let { year, month } = this.nextMonth(this.currentYear, this.currentMonth)

            this.currentYear= year

            this.currentMonth= month

            this.getCurrentArr()

        },

    },

}

export default calendar;

好了,接下来就是正题了

// 获取当月数据,返回数组

getCurrentArr(){

    //发起ajax请求

    this.$axios.post(

        '/api/xxxxxxxxxx'

    ).then((response)=>{

        //获取到这样的一个月的数据

        //date:日期,state:日期状态(预约成功、是否可预约等状态),num:剩余数量(根据需求更改)。字段和字段个数可自定义、新增、修改,如有改动字段,HTML需要跟着修改相应字段

        // let data = [

            //    {date:'2021-12-5', state:0, num: 4},

            //    {date:'2021-12-8', state:1, num: 4},

            //    {date:'2021-12-9', state:0, num: 0},

            //    {date:'2021-12-10', state:0, num: 10},

            //    {date:'2021-12-11', state:0, num: 10},

            //    {date:'2021-12-26', state:0, num: 0},

            //    {date:'2021-12-27', state:0, num: 5},

        // ]

    })

    let currentMonthDateLen = this.getDateLen(this.currentYear, this.currentMonth) // 获取当月天数

    //由于后端传来的日期是断断续续的,我们需要当月不间断的数据,所以没办法自己重新循环整合数据,如果后端传的是连续一个月的就不需要整合了

    let currentMonthDateArr = [] // 定义空数组

    if (currentMonthDateLen > 0) {

        for (let i = 1; i <= currentMonthDateLen; i++) {

            currentMonthDateArr.push({

                month: 'current', // 只是为了增加标识,区分上下月

                date: i,

                state: null,

                num: null

            })

            for (let a = 0; a < data.length; a++) {

                const element = data[a];

                if(this.currentYear+'-'+this.currentMonth+'-'+i == data[a].date){

                    currentMonthDateArr[i-1].state = data[a].state

                    currentMonthDateArr[i-1].num = data[a].num

                    continue

                }

            }

        }

    }

    //如果是连续一个月的数据到这里之上的都可以不需要

    this.currentMonthDateLen=currentMonthDateLen

    //参数说明:后端传来的连续数据或自己整合的连续数据

    this.getAllArr(currentMonthDateArr)

},

到这里,就结束了js

下面我们再来看看html(文章前面能复制,这里只是说明)

根据需求修改

最后,这套代码已经满足我现在的需求了,当然还有很多地方需要完善,欢迎评论区留言,希望能帮助一部分码农

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容