微信小程序组件 日历

js文件

\'use strict\';

let choose_year = null,

choose_month = null;

const conf = {

data: {

hasEmptyGrid: false,

showPicker: false

},

onLoad() {

const date = new Date();

const cur_year = date.getFullYear();

const cur_month = date.getMonth() + 1;

const weeks_ch = [ \'日\', \'一\', \'二\', \'三\', \'四\', \'五\', \'六\' ];

this.calculateEmptyGrids(cur_year, cur_month);

this.calculateDays(cur_year, cur_month);

this.setData({

cur_year,

cur_month,

weeks_ch

});

},

getThisMonthDays(year, month) {

return new Date(year, month, 0).getDate();

},

getFirstDayOfWeek(year, month) {

console.log(new Date(Date.UTC(year, month - 1, 1)).getDay())

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

},

calculateEmptyGrids(year, month) {

const firstDayOfWeek = this.getFirstDayOfWeek(year, month);

let empytGrids = [];

if (firstDayOfWeek > 0) {

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

empytGrids.push(i);

}

this.setData({

hasEmptyGrid: true,

empytGrids

});

} else {

this.setData({

hasEmptyGrid: false,

empytGrids: []

});

}

},

calculateDays(year, month) {

let days = [];

const thisMonthDays = this.getThisMonthDays(year, month);

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

days.push({

day: i,

choosed: false

});

}

this.setData({

days

});

},

// 顶部年月选择控制函数

handleCalendar(e) {

const handle = e.currentTarget.dataset.handle;

const cur_year = this.data.cur_year;

const cur_month = this.data.cur_month;

if (handle === \'prev\') {

let newMonth = cur_month - 1;

let newYear = cur_year;

if (newMonth < 1) {

newYear = cur_year - 1;

newMonth = 12;

}

this.calculateDays(newYear, newMonth);

this.calculateEmptyGrids(newYear, newMonth);

this.setData({

cur_year: newYear,

cur_month: newMonth

});

} else {

let newMonth = cur_month + 1;

let newYear = cur_year;

if (newMonth > 12) {

newYear = cur_year + 1;

newMonth = 1;

}

this.calculateDays(newYear, newMonth);

this.calculateEmptyGrids(newYear, newMonth);

this.setData({

cur_year: newYear,

cur_month: newMonth

});

}

},

tapDayItem(e) {

const idx = e.currentTarget.dataset.idx;

const days = this.data.days;

days[ idx ].choosed = !days[ idx ].choosed;

this.setData({

days,

});

},

chooseYearAndMonth() {

const cur_year = this.data.cur_year;

const cur_month = this.data.cur_month;

let picker_year = [],

picker_month = [];

for (let i = 1900; i <= 2100; i++) {

picker_year.push(i);

}

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

picker_month.push(i);

}

const idx_year = picker_year.indexOf(cur_year);

const idx_month = picker_month.indexOf(cur_month);

this.setData({

picker_value: [ idx_year, idx_month ],

picker_year,

picker_month,

showPicker: true,

});

},

pickerChange(e) {

const val = e.detail.value;

choose_year = this.data.picker_year[val[0]];

choose_month = this.data.picker_month[val[1]];

},

tapPickerBtn(e) {

const type = e.currentTarget.dataset.type;

const o = {

showPicker: false,

};

if (type === \'confirm\') {

o.cur_year = choose_year;

o.cur_month = choose_month;

this.calculateEmptyGrids(choose_year, choose_month);

this.calculateDays(choose_year, choose_month);

}

this.setData(o);

},

onShareAppMessage() {

return {

title: \'小程序日历\',

desc: \'还是新鲜的日历哟\',

path: \'pages/index/index\'

};

}

};

Page(conf);

//--------------------------------------------------------------------------------------------------------------------------------------------------------------------

wxml

<view class="flex box box-tb box-align-center">

<view class="calendar pink-color box box-tb">

<view class="top-handle fs28 box box-lr box-align-center box-pack-center">

<view class="prev box box-rl" bindtap="handleCalendar" data-handle="prev">

<view class="prev-handle box box-lr box-align-center box-pack-center">《</view>

</view>

<view bindtap="chooseYearAndMonth" class="date-area box box-lr box-align-center box-pack-center">{{cur_year || "--"}} 年 {{cur_month || "--"}} 月</view>

<view class="next box box-lr" bindtap="handleCalendar" data-handle="next">

<view class="next-handle box box-lr box-align-center box-pack-center">》</view>

</view>

</view>

<view class="weeks box box-lr box-pack-center box-align-center">

<view class="flex week fs28" wx:for="{{weeks_ch}}" wx:key="week{{index}}" data-idx="{{index}}">{{item}}</view>

</view>

<view class="days box box-lr box-wrap">

<view wx:if="{{hasEmptyGrid}}" class="grid white-color box box-align-center box-pack-center" wx:for="{{empytGrids}}" wx:key="day{{index}}" data-idx="{{index}}">

</view>

<view class="grid white-color box box-align-center box-pack-center" wx:for="{{days}}" wx:key="days{{index}}" data-idx="{{index}}" bindtap="tapDayItem">

<view class="day {{item.choosed ? \'border-radius pink-bg\' : \'\'}} box box-align-center box-pack-center">{{item.day}}</view>

</view>

</view>

</view>

</view>

<view wx:if="{{showPicker}}" class="box box-tb">

<view class="picker-btns box box-lr box-pack-between box-align-center">

<view class="picker-btn picker-cancel" data-type="cancel" bindtap="tapPickerBtn">取消</view>

<view class="picker-btn picker-confirm" data-type="confirm" bindtap="tapPickerBtn">确定</view>

</view>

<picker-view class="flex" indicator- value="{{picker_value}}" bindchange="pickerChange">

<picker-view-column>

<view class="picker-view" wx:key="years{{index}}" wx:for="{{picker_year}}" >{{item}}年</view>

</picker-view-column>

<picker-view-column>

<view class="picker-view" wx:key="months{{index}}" wx:for="{{picker_month}}" >{{item}}月</view>

</picker-view-column>

</picker-view>

</view>

//--------------------------------------------------------------------------------------------------------------------------------------------------------------------

wxss

/* pages/calendar/calendar.wxss */

.top-handle {

height: 80rpx;

}

.prev {

text-align: right;

height: 80rpx;

}

.next {

height: 80rpx;

}

.prev-handle {

width: 80rpx;

height: 100%;

}

.next-handle {

width: 80rpx;

height: 100%;

}

.date-area {

width: 50%;

height: 80rpx;

text-align: center;

}

.weeks {

height: 50rpx;

line-height: 50rpx;

opacity: 0.5

}

.week {

text-align: center;

}

.days {

height: 500rpx;

}

.grid {

width: 107.1428571429rpx;

}

.day {

width: 60rpx;

height: 60rpx;

color: #88d2ac;

font-size: 26rpx;

font-weight: 200;

}

.border-radius {

border-radius: 50%;

position: relative;

left: 0;

top: 0;

color: #fff;

}

.pink-bg {

">#ff629a;

}

.purple-bg {

">#b8b8f1;

}

.right-triangle::after {

content: "";

display: block;

width: 0;

height: 0;

border: 15rpx solid transparent;

border-left-color: #ff629a;

position: absolute;

right: -22rpx;

top: 18rpx;

}

.left-triangle::before {

content: "";

display: block;

width: 0;

height: 0;

border: 15rpx solid transparent;

border-right-color: #ff629a;

position: absolute;

left: -22rpx;

top: 18rpx;

}

.tips {

text-align: center;

margin-top: 20rpx;

margin-bottom: 20rpx;

}

.types {

">#ffedf4;

height: 50rpx;

}

.type-dot {

width: 25rpx;

height: 25rpx;

border-radius: 50%;

margin-right: 10rpx;

}

.type-dot-ymq {

color:#FF7CA0;

">#FF7CA0;

}

.type-dot-ycq {

color: rgb(255, 200, 202);

">rgb(255, 200, 202);

}

.type-dot-aqq {

color: rgb(118, 191, 92);

">rgb(118, 191, 92);

}

.type-dot-yyq {

color: #FF7CA0;

">#FF7CA0;

}

.type-dot-plr {

color: rgb(211, 189, 215);

">rgb(211, 189, 215);

}

.types-desc {

padding: 0 20rpx;

}

.type-name {

margin-top: 50rpx;

margin-bottom: 30rpx;

}

.type-desc {

padding: 0 35rpx;

line-height: 38rpx;

}

.explain {

border-top: 1px solid #eee;

width: 90%;

margin: 20rpx 5% 20rpx 5%;

padding: 20rpx 0;

}

.explain-title {

font-weight: bold;

margin-bottom: 15rpx;

}

.explain-item {

padding: 8rpx 20rpx;

color: #fff;

}

.left-border-radius {

border-top-left-radius: 20rpx;

border-bottom-left-radius: 20rpx;

}

.right-border-radius {

border-top-right-radius: 20rpx;

border-bottom-right-radius: 20rpx;

}

.picker-btns {

height: 120rpx;

line-height: 120rpx;

border-bottom: 1rpx solid #FF7CA0;

}

.picker-confirm {

margin-right: 50rpx;

}

.picker-cancel {

margin-left: 50rpx;

}

.picker-view {

color:#FF7CA0;

text-align: center;

}