写小程序的时候实在不喜欢小程序从下方弹出的默认日历,毕竟丑还不好操作,所以从网上找了个日历组件
写博客记录的时候找了一早上原来的抄袭的博客,实在抱歉没找到,如有博客原著看到麻烦留个言,我加上转载
1、效果图片:
2、js代码
// components/calendar/calendar.js
/**
* 日历选择组件
* 2018-03-04
* mehaotian
* github :https://github.com/mehaotian
*/
Component({
/**
* 组件的属性列表
* data [Date] 当前现实的月份
* selected [Array] 所有被选择的天
*/
properties: {
date: {
type: null,
value: new Date()
},
selected: {
type: Array,
value: [],
observer(newVal, oldVal) {
this.getWeek(new Date())
}
},
isOpen: {
type: Boolean,
value: false,
}
},
/**
* 组件的初始数据
*/
data: {
calShow: true, // 日历组件是否打开
dateShow: false, // 日期是否选择
selectDay: '', // 当前选择日期
canlender: {
"weeks": []
}
},
ready() {
this.getWeek(new Date())
if (this.data.isOpen) {
this.setData({
calShow: false,
dateShow: true
})
}
},
/**
* 组件的方法列表
*/
methods: {
dateSelection() {
if (this.data.isOpen) {
return
}
let self = this;
if (self.data.calShow) {
self.setData({
calShow: false
}, () => {
setTimeout(() => {
self.setData({
dateShow: true
}, () => {
self.triggerEvent('select', { ischeck: !self.data.calShow })
})
}, 100)
})
} else {
self.setData({
dateShow: false
}, () => {
setTimeout(() => {
self.setData({
calShow: true
}, () => {
self.triggerEvent('select', { ischeck: !self.data.calShow })
})
}, 300)
})
}
},
selectDay(e) {
let index = e.currentTarget.dataset.index;
let week = e.currentTarget.dataset.week;
let ischeck = e.currentTarget.dataset.ischeck;
let canlender = this.data.canlender;
if (!ischeck) return false;
let month = canlender.weeks[week][index].month < 10 ? "0" + canlender.weeks[week][index].month : canlender.weeks[week][index].month
let date = canlender.weeks[week][index].date < 10 ? "0" + canlender.weeks[week][index].date : canlender.weeks[week][index].date
this.getWeek(canlender.year + "-" + month + "-" + date);
},
packup() {
let self = this;
if (this.data.isOpen) {
let year = self.data.canlender.year + "-" + self.data.canlender.month + "-" + self.data.canlender.date
let _date = self.getDate(year, 0);
self.getWeek(_date);
return
}
self.setData({
dateShow: false
}, () => {
setTimeout(() => {
self.setData({
calShow: true
}, () => {
let year = self.data.canlender.year + "-" + self.data.canlender.month + "-" + self.data.canlender.date
let _date = self.getDate(year, 0);
self.getWeek(_date);
self.triggerEvent('select', { ischeck: !self.data.calShow })
})
}, 300)
})
},
// 返回今天
backtoday() { this.getWeek(new Date()); },
// 前一天|| 后一天
dataBefor(e) {
let num = 0;
let types = e.currentTarget.dataset.type;
if (e.currentTarget.dataset.id === "0") {
num = -1;
} else {
num = 1
}
let year = this.data.canlender.year + "-" + this.data.canlender.month + "-" + this.data.canlender.date
let _date = this.getDate(year, num, types === 'month' ? "month" : "day");
this.getWeek(_date);
},
// 获取日历内容
getWeek(dateData) {
let selected = this.data.selected
let a = new Date()
// console.log("im date ", a, typeof a === 'object')
// 判断当前是 安卓还是ios ,传入不容的日期格式
if (typeof dateData !== 'object') {
dateData = dateData.replace(/-/g, "/")
}
let _date = new Date(dateData);
let year = _date.getFullYear(); //年
let month = _date.getMonth() + 1; //月
let date = _date.getDate();//日
let day = _date.getDay();// 天
let canlender = [];
// console.log(selected)
let dates = {
firstDay: new Date(year, month - 1, 1).getDay(),
lastMonthDays: [],// 上个月末尾几天
currentMonthDys: [], // 本月天数
nextMonthDays: [], // 下个月开始几天
endDay: new Date(year, month, 0).getDay(),
weeks: []
}
// 循环上个月末尾几天添加到数组
for (let i = dates.firstDay; i > 0; i--) {
dates.lastMonthDays.push({
'date': new Date(year, month, -i).getDate() + '',
'month': month - 1
})
}
// 循环本月天数添加到数组
for (let i = 1; i <= new Date(year, month, 0).getDate(); i++) {
let have = false;
for (let j = 0; j < selected.length; j++) {
let selDate = selected[j].date.split('-');
if (Number(year) === Number(selDate[0]) && Number(month) === Number(selDate[1]) && Number(i) === Number(selDate[2])) {
have = true;
}
}
dates.currentMonthDys.push({
'date': i + "",
'month': month,
have
})
}
// 循环下个月开始几天 添加到数组
for (let i = 1; i < 7 - dates.endDay; i++) {
dates.nextMonthDays.push({
'date': i + '',
'month': month + 1
})
}
canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
// 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天
for (let i = 0; i < canlender.length; i++) {
if (i % 7 == 0) {
dates.weeks[parseInt(i / 7)] = new Array(7);
}
dates.weeks[parseInt(i / 7)][i % 7] = canlender[i]
}
// 渲染数据
this.setData({
selectDay: year+"/"+ month + "/" + date,
"canlender.weeks": dates.weeks,
'canlender.month': month,
'canlender.date': date,
"canlender.day": day,
'canlender.year': year,
})
month = month < 10 ? "0" + month : month
date = date < 10 ? "0" + date : date
this.triggerEvent('getdate', { year, month, date })
},
/**
* 时间计算
*/
getDate(date, AddDayCount, str = 'day') {
if (typeof date !== 'object') {
date = date.replace(/-/g, "/")
}
let dd = new Date(date)
switch (str) {
case 'day':
dd.setDate(dd.getDate() + AddDayCount)// 获取AddDayCount天后的日期
break;
case 'month':
dd.setMonth(dd.getMonth() + AddDayCount)// 获取AddDayCount天后的日期
break;
case 'year':
dd.setFullYear(dd.getFullYear() + AddDayCount)// 获取AddDayCount天后的日期
break;
}
let y = dd.getFullYear()
let m = (dd.getMonth() + 1) < 10 ? '0' + (dd.getMonth() + 1) : (dd.getMonth() + 1)// 获取当前月份的日期,不足10补0
let d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate()// 获取当前几号,不足10补0
return y + '-' + m + '-' + d
}
}
})
2、wxml代码段
<!-- <view class="header space-between"> -->
<!-- <text class="iconfont" data-id="0" bindtap='dataBefor'>
<text class='left color'></text>
</text> -->
<view bindtap="dateSelection">
<image style='width:35px;height:35px' src='/image/time.png'></image>
<!-- <view class="text">{{selectDay}}</view>
<text class=""></text> -->
</view>
<!-- <text class="iconfont" data-id="1" bindtap='dataBefor'>
<text class='right color'></text>
</text> -->
<!-- </view> -->
<view wx:if='{{!calShow}}' class="{{isOpen?'':'calendar-box'}} {{dateShow?'active':''}}" style='z-index:100'>
<view class="calendar-wrapper {{dateShow?'active':''}}">
<view class="calendar-panel">
<view class="date-befor" data-id="0" data-type="month" bindtap='dataBefor'>
<text class="iconfont">
<text class='left color'></text>
</text>
</view>
<view class="calendar-panel-box">
<view>{{canlender.year}}年</view>
<view>{{canlender.month}}月</view>
</view>
<view class="date-after" data-id="1" data-type="month" bindtap='dataBefor'>
<text class="iconfont">
<text class='right color'></text>
</text>
</view>
<view class='backtoday' bindtap='backtoday'>
回到今天
</view>
</view>
<view class="calendar-header">
<view>日</view>
<view>一</view>
<view>二</view>
<view>三</view>
<view>四</view>
<view>五</view>
<view>六</view>
</view>
<view class="calendar-body">
<block wx:for="{{canlender.weeks}}" wx:for-item="weeks" wx:for-index="week" wx:key="weeks">
<view class="calender-body-date-week">
<block wx:for="{{weeks}}" wx:for-item="day" wx:key="day">
<view class="date {{canlender.month === day.month? '' : 'placeholder'}} {{(day.date==canlender.date||day.checked) && canlender.month == day.month?'date-current': ''}} " data-week="{{week}}" data-index="{{index}}" data-ischeck="{{canlender.month === day.month}}"
bindtap='selectDay'>
{{day.date}}
<view wx:if="{{day.have}}" class="data-circle"></view>
</view>
</block>
</view>
</block>
</view>
<view class="packup" bindtap='packup'>确定</view>
</view>
</view>
3、json代码段
{
"component": true,
"usingComponents": {}
}
4、wxss代码段
/* pages/calendar/calendar.wxss */
.calendar-box {
position: absolute;
top: 10%;
left: 0;
width: 100%;
height: 100vh;
background: rgba(0, 0, 0, 0);
z-index: 999;
padding-top: 100rpx;
box-sizing: border-box;
transition: all 0.3s;
opacity: 0;
}
.calendar-box.active {
opacity: 1;
}
.calendar-wrapper {
width: 100%;
border-top: 1px #f5f5f5 solid;
box-sizing: border-box;
font-size: 26rpx;
background: #fff;
transition: all 0.3s;
transform: translateY(-100%);
}
.calendar-wrapper.active {
transform: translateY(0%);
}
.header {
display: flex;
justify-content: center;
align-items: center;
position: relative;
height: 100rpx;
/* width: 100%; */
background: #fff;
/* padding: 0 30rpx; */
z-index: 10000;
}
.top-jiantou {
width: 100rpx;
height: 100rpx;
text-align: center;
box-sizing: border-box;
line-height: 100rpx;
}
.iconfont {
display: flex;
justify-content: center;
align-items: center;
position: relative;
color: #52b8f5;
width: 40rpx;
height: 35rpx;
}
.iconfont .left, .iconfont .right {
display: block;
width: 0;
height: 0;
border-top: 20rpx solid transparent;
border-bottom: 20rpx solid transparent;
}
.iconfont .left {
border-right: 40rpx solid transparent;
}
.iconfont .right {
border-left: 40rpx solid transparent;
}
.iconfont .left.color {
border-right-color: #52b8f5;
}
.iconfont .right.color {
border-left-color: #52b8f5;
}
.btn {
margin: 0 30rpx;
width: 240rpx;
height: 53rpx;
border: 1rpx solid #52b8f5;
border-radius: 26rpx;
color: #52b8f5;
font-size: 26rpx;
box-sizing: border-box;
}
.calendar-panel {
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
height: 80rpx;
}
.backtoday {
position: absolute;
right: 0;
top: 15rpx;
padding: 0 10rpx;
padding-left: 5%;
height: 50rpx;
line-height: 50rpx;
border: 1px #52b8f5 solid;
border-right: none;
font-size: 28rpx;
border-top-left-radius: 50rpx;
border-bottom-left-radius: 50rpx;
color: #52b8f5;
background: rgba(82, 184, 245, 0.1);
}
.date-befor, .date-after {
/* border: 1px red solid; */
display: flex;
justify-content: center;
align-items: center;
height: 80rpx;
width: 80rpx;
text-align: center;
line-height: 80rpx;
/* margin-right: 20rpx; */
}
/* .date-after {
margin-left: 20rpx;
} */
.calendar-panel-box {
display: flex;
}
.calendar-header {
display: flex;
}
.calendar-header view {
width: 100%;
text-align: center;
line-height: 80rpx;
color: #52b8f5;
}
.calendar-body {
display: flex;
flex-wrap: wrap;
}
.calender-body-date-week {
display: flex;
width: 100%;
border-bottom: 1px #f5f5f5 solid;
}
.date {
position: relative;
width: 100%;
text-align: center;
color: #1c1c1c;
background: #fff;
line-height: 100rpx;
}
.date.active {
background: red;
}
.placeholder {
color: #a4a4a4;
}
.date-current {
background: #52b8f5;
color: #fff;
}
.data-circle {
position: absolute;
bottom: 10rpx;
left: 0;
right: 0;
margin: auto;
width: 10rpx;
height: 10rpx;
border-radius: 50%;
background: #ff5a5f;
z-index: 2;
}
.packup {
width: 100%;
height: 100rpx;
line-height: 100rpx;
text-align: center;
color: #52b8f5;
}
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
5、使用方法
5.1、在需要使用的页面先注册,.json文件中
"usingComponents": {"calendar": "../../components/calendar/calendar"},
calendar组件名
../../components/calendar/calendar组件地址
5.2、在.wxml文件中
<calendar bindselect="bindselect" bindgetdate="bindgetdate"></calendar>
5.3、在.js文件中
bindselect(e) { var that = this console.log("点击日历图标=" + JSON.stringify(that)) },//日历组件控制 bindgetdate(e) { console.log("选择日期=" + e.detail.year + "-" + e.detail.month + "-" + e.detail.date) },//获取选择的日期
6、组件显示样式可在底层文件中更改
7、说几个没完善的地方,方法bindselect(e)可添加二次点击收起弹出,点击灰色部分日期时(非当前月所显示的日期)可添加跳转到点击月,并且选中方法
8、当前组件提供了代码块可导入编辑器查看
个人github博客转载18487115313.github.io
网友评论