微信小程序-自定义日历组件(二)进阶

412 阅读1分钟

这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战

要实现一个日历组件,切换周日历和月日历,之前月日历已经实现过,下面就是先实现周日历,然后就是各种切换,点击,展开收起时候的调用和选中问题,其中也遇到很多小小的问题,最终解决了,记录一下。。

如下图的效果,默认是周,展开是月,点击选中,展示一周或者一个月的事件,有事件的日期下面有一个标识,选中的日期的标识是白色的,默认选择今天。 微信图片_20211115154206.png

微信图片_20211115154213.png

子组件的html代码

主要包括切换月份和日历的代码

<view class="calendar-container">
    <view class="choose-month d-fx">
        <view class="order-title">预约测试时间表</view>
        <view class="month-left">
            <view class="left-par">
                <text class="iconfont iconxiangyou black-45" 
                bindtap="chooseMonth" data-state="-1"></text>
            </view>
            <text class="title">{{year}}年{{month}}月</text>
            <view class="right-par">
                <text class="iconfont icongengduo black-45" 
                bindtap="chooseMonth" data-state="1"></text>
            </view>
        </view>
    </view>
    <view class="days-area">
        <view class="day week black-65 fs12" wx:for="{{weeks}}" 
        wx:key="index">{{item}}</view>
            <view wx:for="{{days}}" wx:key="index" 
                wx:for-item="day"
                class="day day-time fs12 
                {{day.chooseDay?'choose-day':day.isToday?'today': ''}}
                {{day.className}} {{day.event?'day-event':''}}"
                bindtap="chooseThisDay" 
                data-year="{{day.year}}" 
                data-month="{{day.month}}"
                data-gregorian="{{day.gregorian}}" 
                data-className="{{day.className}}">{{day.title}}
           </view>
    </view>
</view>

子组件的js代码

日历组件的代码,其中observer是监听,可以在父组件传值过来时候进行立刻监听。

/**
 * 组件的属性列表
 */
properties: {
    isFirst: {
        type: Boolean
    },
    type: {
        type: String,// 监听type变化,切换日期
        observer: function (e) {
            if (!this.data.isFirst) {
                return;
            }
            // 今天的日期
            if (this.data.isStart) {
                let now = new Date();
                this.setData({
                    year: now.getFullYear(),
                    month: now.getMonth() + 1,
                    today: now.getDate(),
                    yearNow: now.getFullYear(),
                    monthNow: now.getMonth() + 1,
                    todayNow: now.getDate(),
                    isStart: false
                })
            }
            if (this.data.type == 1) {
                this.getWeekDay(); // 周渲染
            } else {
                this.getDays(); // 日历渲染
            }
            this.setData({
                isFirst: false
            })
            this.getEventsList(); // 事件
        }
    },
},
data: {
    year: 0,// 点击的日期
    month: 0,
    today: 0,
    yearNow: 0,// 今天的日期
    monthNow: 0,
    todayNow: 0,
    days: [], // 日期数组
    weeks: ['日', '一', '二', '三', '四', '五', '六'], // 周次
}
// 获取周日期
getWeekDay() {
    this.data.days = [];// 日期数组
    var currentDate = new Date(this.data.year, this.data.month - 1, this.data.today)
    var timesStamp = currentDate.getTime();
    var currenDay = currentDate.getDay();
    var dates = [];
    for (var i = 0; i < 7; i++) {
        dates.push(format(new Date(timesStamp + 24 * 60 * 60 * 1000 * (i - (currenDay + 7) % 7))));
    }
    for (let i = 0; i < dates.length; i++) {
        let year = dates[i].split("-")[0],
            month = dates[i].split("-")[1],
            gregorian = dates[i].split("-")[2],
            title = gregorian,
            chooseDay = false;
        if (year == this.data.yearNow && month == this.data.monthNow && gregorian == this.data.todayNow) {
            title = '今';
            chooseDay = true;
        }
        this.data.days.push({
            year: year,
            month: month,
            title: title,
            gregorian: gregorian,
            className: '',
            chooseDay: chooseDay // 默认选中今天
        })
    }
    this.setData({
        days: this.data.days
    })
    let dayStart = this.data.days[0],
        dayEnd = this.data.days[this.data.days.length - 1];
    let starDate = dayStart.year + '-' + dayStart.month + '-' + dayStart.gregorian + ' 00:00:00';
    let endDate = dayEnd.year + '-' + dayEnd.month + '-' + dayEnd.gregorian + ' 23:59:59';
    this.setData({
        starDate: starDate,
        endDate: endDate,
        type: '1',// 1 周日历 2月日历
    })
},

其中月日历的js代码在之前的一篇文章 # 微信小程序-自定义日历组件 有介绍过,这次就不过多介绍重复代码了,只说新加的功能。

// 获取当前月日期
getDays() {
    ...省略代码
    let dayStart = this.data.days[0],
    dayEnd = this.data.days[this.data.days.length - 1];
let starDate = dayStart.year + '-' + dayStart.month + '-' + dayStart.gregorian + ' 00:00:00';
let endDate = dayEnd.year + '-' + dayEnd.month + '-' + dayEnd.gregorian + ' 23:59:59';
    this.setData({
        starDate: starDate,
        endDate: endDate,
        type: '2',// 1 周日历 2月日历
    })
}

父组件的html代码

包括调用日历组件和展开收起按钮

<!-- 日历 -->
<calendar-order bindonCalendarClick="onCalendarClick" type="{{type}}" isFirst="{{isFirst}}">
</calendar-order>
<view class="d-fx p-l-r-30" bindtap="changeToAll">
    <text class="line"></text>
    <van-icon name="arrow-down" wx:if="{{type == 1}}" color="rgba(0, 0, 0, 0.3)" size="40rpx" />
    <van-icon name="arrow-up" wx:if="{{type == 2}}" color="rgba(0, 0, 0, 0.3)" size="40rpx" />
    <text class="line"></text>
</view>

父组件js代码

// 点击某一天选择日历
onCalendarClick(e) {
    let item = e.detail;
    this.setData({
        date: item.year + "-" + item.month + "-" + item.today + " " + "00:00",
        type: item.type
    })
},
// 周-月日历切换
changeToAll() {
    this.setData({
        type: this.data.type == '1' ? '2' : '1',
        isFirst: true,
    })
},

以上就是日历组件的全部代码了,记录一下,温故而知新