微信小程序_自定义日历组件

话不多说,先上图片,看一下效果是否是我们需要的,以下为效果图:
在这里插入图片描述
这是定义的组件

calendars.wxml

首先,在我们自己创建的calendars.wxml中写入我们需要的格式,上代码:

<view class="components-calendars-bg" wx:if="{{show}}">
<view class="components-calendars">
	<!--显示当前年月日-->
	<view class='calendar-title'>
		<view class='item ctrl' bindtap='lastMonth'>{{lastMonth}}</view>
		<view class='item title'>{{title}}</view>
		<view class='item ctrl' bindtap='nextMonth'>{{nextMonth}}</view>
		<view class='item ctrl today' bindtap='today'>今天</view>
	</view>

	<!--遍历星期-->
	<view class='calendar-week'>
		<view wx:for='{{weekText}}' class='item' wx:key='item'>{{item}}</view>
	</view>

	<view class='calendar-container'>
		<!--上个月占位格子-->
		<view class='grid gray' wx:for='{{empytGridsBefore}}' wx:key='item'>{{item}}</view>

		<!--当月格子-->
		<view class='grid' wx:for='{{thisMonthDays}}' wx:key='index'>
			<view class='self' wx:if="{{ format === year+'-'+item.monthFormat+'-'+item.dateFormat }}"></view>
			<view class="wrap {{ select === year+'-'+item.monthFormat+'-'+item.dateFormat ? 'select' : ''}}" bindtap='select' data-date='{{item.date}}'>{{item.date}}</view>
		</view>

		<!--下个月占位格子-->
		<view class='grid gray' wx:for='{{empytGridsAfter}}' wx:key='item'>{{item}}</view>
	</view>

	<view class="calendar-btn">
		<view class="cancel" bindtap="cancel">取消</view>
		<view class="confirm" bindtap="confirm">确定</view>
	</view>

    </view>
</view>

calendars.wxss中的样式:

我们可以根据自己的需要修改样式

body {
  height: 100%;
  position: relative;
}

.components-calendars-bg {
  width: 100%;
  height: 100%;
  background-color: rgb(0, 0, 0, .9);
  position: absolute;
  z-index: 888;
  display: flex;
  align-items: center;
  justify-content: center;
}

.components-calendars {
  width: 80%;
  background-color: #eee;
  text-align: center;
  font-size: 30rpx;
  box-sizing: border-box;
  border-radius: 10rpx;
  z-index: 999;
}

/* 标题 */

.calendar-title {
  line-height: 70rpx;
  font-size: 30rpx;
  text-align: left;
  padding: 0 20rpx;
  box-sizing: border-box;
}

.calendar-title .ctrl {
  display: inline-block;
  padding: 0 20rpx;
  background: #f5f5f5;
  border-radius: 10rpx;
}

.calendar-title .item {
  display: inline-block;
  vertical-align: middle;
  line-height: 50rpx;
}

.calendar-title .title {
  min-width: 300rpx;
  text-align: center;
}

.calendar-title .today {
  float: right;
  margin-top: 10rpx;
}

/* 星期 */

.calendar-week {
  display: flex;
  text-align: center;
  padding: 20rpx 10rpx;
  box-sizing: border-box;
  border-top: 1rpx solid #e0e0e0;
  border-bottom: 1rpx solid #e0e0e0;
  background: #f5f5f5;
}

.calendar-week .item {
  flex: 1;
}

/* 日期 */

.calendar-container {
  display: flex;
  flex-wrap: wrap;
  padding: 20rpx 10rpx;
  box-sizing: border-box;
}

.calendar-container .grid {
  display: inline-block;
  width: 14.28571428571429%;
  line-height: 70rpx;
  position: relative;
  z-index: 1;
}

.calendar-container .grid .self {
  position: absolute;
  top: 0rpx;
  right: 0rpx;
  width: 15rpx;
  height: 15rpx;
  border-radius: 50%;
  background: red;
  border: 3rpx solid #fff;
}

.calendar-container .grid.gray {
  color: #ccc;
}

.calendar-container .grid .wrap.select {
  background: #54b442;
  border-radius: 50%;
  color: #fff;
  width: 80%;
  margin: 0 auto;
}

.calendar-btn {
  height: 80rpx;
  background-color: #f5f5f5;
  display: flex;
  align-items: center;
  justify-content: space-around;
  /* justify-content:; */
  border-top:2rpx solid #e0e0e0 ; 
  border-bottom-left-radius: 10rpx;
  border-bottom-right-radius: 10rpx;
}
.calendar-btn .confirm{
  width: 50%;
  line-height: 80rpx;
  color: #54b442;
}
.calendar-btn .cancel{
  width: 50%;
  border-right: 2rpx solid #e0e0e0;
  line-height: 80rpx;
}

calendars.json:

{
  "usingComponents":{}
}

calendars.js中:

Component({
    //初始默认为当前日期
    properties: {
        defaultValue: {
            type: String,
            value: ''
        },
        //星期数组
        weekText: {
            type: Array,
            value: ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
        },
        lastMonth: {
            type: String,
            value: '◀'
        },
        nextMonth: {
            type: String,
            value: '▶'
        },
        show: {
            type: Boolean,
            value: '',
            observer: 'showChange'
        }

    },

    // 组件的初始数据
    data: {
        //当月格子
        thisMonthDays: [],
        //上月格子
        empytGridsBefore: [],
        //下月格子
        empytGridsAfter: [],
        //显示日期
        title: '',
        //格式化日期
        format: '',

        year: 0,
        month: 0,
        date: 0,
        toggleType: 'large',
        scrollLeft: 0,
        //常量 用于匹配是否为当天
        YEAR: 0,
        MONTH: 0,
        DATE: 0,
    },
    ready: function () {
        this.today();
    },

    methods: {
        showChange(show) {
            this.setData({
                show
            })
            const _this = this
            if (show) {
              setTimeout(() => {
                _this.setData({
                  show: true
                })
              }, this.data.duration)
            }
        },

        //初始化
        display: function (year, month, date) {
            this.setData({
                year,
                month,
                date,
                title: year + '年' + this.zero(month) + '月',
                // title: year + '年' + this.zero(month) + '月' + this.zero(date) + '日',
            })
            this.createDays(year, month);
            this.createEmptyGrids(year, month);
        },
        //默认选中当天 并初始化组件
        today: function () {
            console.log(this.data.defaultValue)
            console.log(new Date(this.data.defaultValue))
            console.log(new Date())
            let DATE = this.data.defaultValue ? new Date(this.data.defaultValue) : new Date(),
                year = DATE.getFullYear(),
                month = DATE.getMonth() + 1,
                date = DATE.getDate(),
                select = year + '-' + this.zero(month) + '-' + this.zero(date);

            this.setData({
                format: select,
                select: select,
                year: year,
                month: month,
                date: date,
                YEAR: year,
                MONTH: month,
                DATE: date,
            })

            //初始化日历组件UI
            this.display(year, month, date);

            //发送事件监听
            this.triggerEvent('select', select);
        },

        //选择 并格式化数据
        select: function (e) {
            let date = e.currentTarget.dataset.date,
                select = this.data.year + '-' + this.zero(this.data.month) + '-' + this.zero(date);
            this.setData({
                title: this.data.year + '年' + this.zero(this.data.month) + '月' + this.zero(date) + '日',
                select: select,
                year: this.data.year,
                month: this.data.month,
                date: date
            });
            //发送事件监听
            // this.triggerEvent('select', select);
        },
        //上个月
        lastMonth: function () {
            let month = this.data.month == 1 ? 12 : this.data.month - 1;
            let year = this.data.month == 1 ? this.data.year - 1 : this.data.year;
            //初始化日历组件UI
            this.display(year, month, 0);
        },
        //下个月
        nextMonth: function () {
            let month = this.data.month == 12 ? 1 : this.data.month + 1;
            let year = this.data.month == 12 ? this.data.year + 1 : this.data.year;
            //初始化日历组件UI
            this.display(year, month, 0);
        },
        //获取当月天数
        getThisMonthDays: function (year, month) {
            return new Date(year, month, 0).getDate();
        },
        // 绘制当月天数占的格子
        createDays: function (year, month) {
            let thisMonthDays = [],
                days = this.getThisMonthDays(year, month);
            for (let i = 1; i <= days; i++) {
                thisMonthDays.push({
                    date: i,
                    dateFormat: this.zero(i),
                    monthFormat: this.zero(month),
                    week: this.data.weekText[new Date(Date.UTC(year, month - 1, i)).getDay()]
                });
            }
            this.setData({
                thisMonthDays
            })
        },
        //获取当月空出的天数
        createEmptyGrids: function (year, month) {
            let week = new Date(Date.UTC(year, month - 1, 1)).getDay(),
                empytGridsBefore = [],
                empytGridsAfter = [],
                emptyDays = (week == 0 ? 7 : week);
            //当月天数
            var thisMonthDays = this.getThisMonthDays(year, month);
            //上月天数
            var preMonthDays = month - 1 < 0 ?
                this.getThisMonthDays(year - 1, 12) :
                this.getThisMonthDays(year, month - 1);

            //空出日期
            for (let i = 1; i <= emptyDays; i++) {
                empytGridsBefore.push(preMonthDays - (emptyDays - i));
            }

            var after = (42 - thisMonthDays - emptyDays) - 7 >= 0 ?
                (42 - thisMonthDays - emptyDays) - 7 :
                (42 - thisMonthDays - emptyDays);
            for (let i = 1; i <= after; i++) {
                empytGridsAfter.push(i);
            }
            this.setData({
                empytGridsAfter,
                empytGridsBefore
            })
        },

        // 点击确认发送选中的日期
        confirm: function () {
            this.triggerEvent('select',this.data.select)    
            // this.data.show = false
            this.setData({
                show:false
            })
        },
        cancel:function(){
            this.setData({
                show:false
            })
        },

        //补全0
        zero: function (i) {
            return i >= 10 ? i : '0' + i;
        },
    }
})

至此,日历组件就写好了
我们在我们想要用到的这个日历组件的页面把日历组件加进来:

<my-calendars show="{{calendarsShow}}" bind:select="mySelet">	</my-calendars>

show="{{calendarsShow}}" 可以控制组件的显示和隐藏,bind:select" 这个地方绑定的是组件发送过来的事件名称,mySelet,这个事件是为了拿到组件发送(返回)过来的数据
index.js 中加入,

data: {
    calendarsShow:true
  },
methods:{
  mySelet(e){
    this.setData({
      mySeletData:e.detail
    })
  },
}

mySeletData 就是我们需要的日期了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值