微信小程序自定义可滑动日历界面


Posted in Javascript onDecember 28, 2018

本文实例为大家分享了微信小程序可滑动日历界面的具体代码,供大家参考,具体内容如下

参考某个博主的自定义控件做了一些改动,希望这篇博客能帮助需要的人。

WXML

<view class='container'>
<view class='month flex m-around'>
 <view class='arrow' bindtap='prevMonth'>《 </view>
 <view class='year-and-month'>
  <picker mode="date" value="{{date}}" start="2015-09" end="2020-09" fields='month' bindchange="bindDateChange">
  <view>
   {{date}}
  </view>
  </picker>
 </view>
 <view class='arrow' bindtap='nextMonth'> 》</view>
</view>
<view class='calendar flex column s-center'>
 <view class='week-row flex m-around'>
 <view class='grid' wx:for="{{week}}" wx:key='item'>{{item}}</view>
 </view>
 <swiper class='swpier-box' circular="true" current="{{swiperIndex}}" bindchange='swiperChange'>
 <swiper-item class='flex m-around days-table '>
  <view wx:for="{{calendar.first}}" wx:for-item='x' wx:key='x.date'
  class='grid {{x.month === month?"":"notCurrent"}} {{x.date === today?"today":""}} {{x.date == beSelectDate ? "choice":""}}' data-month='{{x.month}}' data-day='{{x.day}}' data-date='{{x.date}}' bindtap='bindDayTap'>
  <view>{{x.date === today?'今天':x.day}}</view>
  </view>
 </swiper-item>
 <swiper-item class='flex m-around days-table '>
  <view wx:for="{{calendar.second}}" wx:for-item='x' wx:key='x.date'
  class='grid {{x.month === month?"":"notCurrent"}} {{x.date === today?"today":""}} {{x.date == beSelectDate ? "choice":""}}' data-month='{{x.month}}' data-day='{{x.day}}' data-date='{{x.date}}' data-test='{{(year + "-" +month + "-" + day)}}' bindtap='bindDayTap'>
  <view>{{x.date === today?'今天':x.day}}</view>
  </view>
 </swiper-item>
 <swiper-item class='flex m-around days-table'>
  <view wx:for="{{calendar.third}}" wx:for-item='x' wx:key='x.date'
  class='grid {{x.month === month?"":"notCurrent"}} {{x.date === today?"today":""}} {{x.date == beSelectDate ? "choice":""}}' data-month='{{x.month}}' data-day='{{x.day}}' data-date='{{x.date}}' bindtap='bindDayTap'>
  <view>{{x.date === today?'今天':x.day}}</view>
  </view>
 </swiper-item>
 <swiper-item class='flex m-around days-table '>
  <view wx:for="{{calendar.fourth}}" wx:for-item='x' wx:key='x.date'
  class='grid {{x.month === month?"":"notCurrent"}} {{x.date === today?"today":""}} {{x.date == beSelectDate ? "choice":""}}' data-month='{{x.month}}' data-day='{{x.day}}' data-date='{{x.date}}' bindtap='bindDayTap'>
  <view>{{x.date === today?'今天':x.day}}</view>
  </view>
 </swiper-item>
 </swiper>
</view>
</view>

CSS

/* pages/calendar/calendar.wxss */
 .container {
 height: 100vh;

 background-color: #393E44;
}
.days-table {
 flex-wrap: wrap;
 align-content: flex-start;
}
.calendar{
 position: fixed;
 z-index:10000;
 background: #393E44;
 
}
.grid {
 width: 107.14rpx;
 height: 100rpx;
 text-align: center;
 line-height: 100rpx;
 font-size:.7rem;
 color:#fff;
}
.today {
 color: #88a1fd;
}
.grid view {
 height:85rpx;
 line-height: 85rpx;
 width:85rpx;
}
.choice view{
 border-radius: 50%;
 background: #88a1fd;
 background-position:center;
 color: white;
}
/* 非本月日期 */
.notCurrent {
 color: silver;
}
.day-hover {
 background: red;
}
.swpier-box {
 height: 550rpx;
 width: 100%;
}
.arrow {
 width: 100rpx;
 color: #88a1fd;
 text-align: center;
}
.year-and-month{
 color: #88a1fd;
}

.flex {
 display: flex;
}
/* 轴向 */
.column {
 flex-direction: column;
}
/* 主轴方向 */
.m-start {
 justify-content: flex-start;
}

.m-end {
 justify-content: flex-end;
}

.m-around {
 justify-content: space-around;
}
.m-between {
 justify-content: space-between;
}
.m-center {
 justify-content: center;
}
/* 侧轴方向 */
.s-start {
 align-items: flex-start;
}
.s-end {
 align-items: flex-end;
}

.s-around {
 align-items: space-around;
}
.s-between {
 align-items: space-between;
}
.s-center {
 align-items: center;
}

JS

// pages/calendar/calendar.js

'use strict';

let choose_year = null,
 choose_month = null;
const conf = {
 data: {
 day: '',
 year: '',
 month: '',
 date: '2017-01',
 today: '',
 week: ['日', '一', '二', '三', '四', '五', '六'],
 calendar: {
  first: [],
  second: [],
  third: [],
  fourth: []
 },
 swiperMap: ['first', 'second', 'third', 'fourth'],
 swiperIndex: 1,
 showCaldenlar: false
 },
 onLoad() {
 const date = new Date()
  , month = this.formatMonth(date.getMonth() + 1)
  , year = date.getFullYear()
  , day = this.formatDay(date.getDate())
  , today = `${year}-${month}-${day}`
 let calendar = this.generateThreeMonths(year, month)

 this.setData({
  calendar,
  month,
  year,
  day,
  today,
  beSelectDate: today,
  date: `${year}-${month}`
 })
 },

 showCaldenlar() {
 this.setData({
  showCaldenlar: !this.data.showCaldenlar
 })
 },
 /**
 * 
 * 左右滑动
 * @param {any} e 
 */
 swiperChange(e) {
 const lastIndex = this.data.swiperIndex
  , currentIndex = e.detail.current
 let flag = false
  , { year, month, day, today, date, calendar, swiperMap } = this.data
  , change = swiperMap[(lastIndex + 2) % 4]
  , time = this.countMonth(year, month)
  , key = 'lastMonth'

 if (lastIndex > currentIndex) {
  lastIndex === 3 && currentIndex === 0
  ? flag = true
  : null
 } else {
  lastIndex === 0 && currentIndex === 3
  ? null
  : flag = true
 }
 if (flag) {
  key = 'nextMonth'
 }

 year = time[key].year
 month = time[key].month
 date = `${year}-${month}`
 day = ''
 if (today.indexOf(date) !== -1) {
  day = today.slice(-2)
 }

 time = this.countMonth(year, month)
 calendar[change] = null
 calendar[change] = this.generateAllDays(time[key].year, time[key].month)

 this.setData({
  swiperIndex: currentIndex,
  //文档上不推荐这么做,但是滑动并不会改变current的值,所以随之而来的计算会出错
  year,
  month,
  date,
  day,
  calendar
 })
 },
 /**
 * 
 * 点击切换月份,生成本月视图以及临近两个月的视图
 * @param {any} year 
 * @param {any} month 
 * @returns {object} calendar
 */
 generateThreeMonths(year, month) {
 let { swiperIndex, swiperMap, calendar } = this.data
  , thisKey = swiperMap[swiperIndex]
  , lastKey = swiperMap[swiperIndex - 1 === -1 ? 3 : swiperIndex - 1]
  , nextKey = swiperMap[swiperIndex + 1 === 4 ? 0 : swiperIndex + 1]
  , time = this.countMonth(year, month)
 delete calendar[lastKey]
 calendar[lastKey] = this.generateAllDays(time.lastMonth.year, time.lastMonth.month)
 delete calendar[thisKey]
 calendar[thisKey] = this.generateAllDays(time.thisMonth.year, time.thisMonth.month)
 delete calendar[nextKey]
 calendar[nextKey] = this.generateAllDays(time.nextMonth.year, time.nextMonth.month)
 return calendar
 },
 bindDayTap(e) {
 let { month, year } = this.data
  , time = this.countMonth(year, month)
  , tapMon = e.currentTarget.dataset.month
  , day = e.currentTarget.dataset.day
 if (tapMon == time.lastMonth.month) {
  this.changeDate(time.lastMonth.year, time.lastMonth.month)
 } else if (tapMon == time.nextMonth.month) {
  this.changeDate(time.nextMonth.year, time.nextMonth.month)
 } else {
  this.setData({
  day
  })
 }
 let beSelectDate = e.currentTarget.dataset.date;
 this.setData({
  beSelectDate,
  showCaldenlar: false
 })
 },
 bindDateChange(e) {
 if (e.detail.value === this.data.date) {
  return
 }

 const month = e.detail.value.slice(-2)
  , year = e.detail.value.slice(0, 4)

 this.changeDate(year, month)
 },
 prevMonth(e) {
 let { year, month } = this.data
  , time = this.countMonth(year, month)
 this.changeDate(time.lastMonth.year, time.lastMonth.month)
 },
 nextMonth(e) {
 let { year, month } = this.data
  , time = this.countMonth(year, month)
 this.changeDate(time.nextMonth.year, time.nextMonth.month)
 },
 /**
 * 
 * 直接改变日期
 * @param {any} year 
 * @param {any} month 
 */
 changeDate(year, month) {
 let { day, today } = this.data
  , calendar = this.generateThreeMonths(year, month)
  , date = `${year}-${month}`
 date.indexOf(today) === -1
  ? day = '01'
  : day = today.slice(-2)

 this.setData({
  calendar,
  day,
  date,
  month,
  year,
 })
 },
 /**
 * 
 * 月份处理
 * @param {any} year 
 * @param {any} month 
 * @returns 
 */
 countMonth(year, month) {
 let lastMonth = {
  month: this.formatMonth(parseInt(month) - 1)
 }
  , thisMonth = {
  year,
  month,
  num: this.getNumOfDays(year, month)
  }
  , nextMonth = {
  month: this.formatMonth(parseInt(month) + 1)
  }

 lastMonth.year = parseInt(month) === 1 && parseInt(lastMonth.month) === 12
  ? `${parseInt(year) - 1}`
  : year + ''
 lastMonth.num = this.getNumOfDays(lastMonth.year, lastMonth.month)
 nextMonth.year = parseInt(month) === 12 && parseInt(nextMonth.month) === 1
  ? `${parseInt(year) + 1}`
  : year + ''
 nextMonth.num = this.getNumOfDays(nextMonth.year, nextMonth.month)
 return {
  lastMonth,
  thisMonth,
  nextMonth
 }
 },
 currentMonthDays(year, month) {
 const numOfDays = this.getNumOfDays(year, month)
 return this.generateDays(year, month, numOfDays)
 },
 /**
 * 生成上个月应显示的天
 * @param {any} year 
 * @param {any} month 
 * @returns 
 */
 lastMonthDays(year, month) {
 const lastMonth = this.formatMonth(parseInt(month) - 1)
  , lastMonthYear = parseInt(month) === 1 && parseInt(lastMonth) === 12
  ? `${parseInt(year) - 1}`
  : year
  , lastNum = this.getNumOfDays(lastMonthYear, lastMonth) //上月天数
 let startWeek = this.getWeekOfDate(year, month - 1, 1) //本月1号是周几
  , days = []
 if (startWeek == 7) {
  return days
 }

 const startDay = lastNum - startWeek

 return this.generateDays(lastMonthYear, lastMonth, lastNum, { startNum: startDay, notCurrent: true })
 },
 /**
 * 生成下个月应显示天
 * @param {any} year 
 * @param {any} month
 * @returns 
 */
 nextMonthDays(year, month) {
 const nextMonth = this.formatMonth(parseInt(month) + 1)
  , nextMonthYear = parseInt(month) === 12 && parseInt(nextMonth) === 1
  ? `${parseInt(year) + 1}`
  : year
  , nextNum = this.getNumOfDays(nextMonthYear, nextMonth) //下月天数
 let endWeek = this.getWeekOfDate(year, month)  //本月最后一天是周几
  , days = []
  , daysNum = 0
 if (endWeek == 6) {
  return days
 } else if (endWeek == 7) {
  daysNum = 6
 } else {
  daysNum = 6 - endWeek
 }
 return this.generateDays(nextMonthYear, nextMonth, daysNum, { startNum: 1, notCurrent: true })
 },
 /**
 * 
 * 生成一个月的日历
 * @param {any} year 
 * @param {any} month 
 * @returns Array
 */
 generateAllDays(year, month) {
 let lastMonth = this.lastMonthDays(year, month)
  , thisMonth = this.currentMonthDays(year, month)
  , nextMonth = this.nextMonthDays(year, month)
  , days = [].concat(lastMonth, thisMonth, nextMonth)
 return days
 },
 /**
 * 
 * 生成日详情
 * @param {any} year 
 * @param {any} month 
 * @param {any} daysNum 
 * @param {boolean} [option={
 * startNum:1,
 * grey: false
 * }] 
 * @returns Array 日期对象数组
 */
 generateDays(year, month, daysNum, option = {
 startNum: 1,
 notCurrent: false
 }) {
 const weekMap = ['一', '二', '三', '四', '五', '六', '日']
 let days = []
 for (let i = option.startNum; i <= daysNum; i++) {
  let week = weekMap[new Date(year, month - 1, i).getUTCDay()]
  let day = this.formatDay(i)
  days.push({
  date: `${year}-${month}-${day}`,
  event: false,
  day,
  week,
  month,
  year
  })
 }
 return days
 },
 /**
 * 
 * 获取指定月第n天是周几 |
 * 9月第1天: 2017, 08, 1 |
 * 9月第31天:2017, 09, 0 
 * @param {any} year 
 * @param {any} month 
 * @param {number} [day=0] 0为最后一天,1为第一天
 * @returns number 周 1-7, 
 */
 getWeekOfDate(year, month, day = 0) {
 let dateOfMonth = new Date(year, month, 0).getUTCDay() + 1;
 dateOfMonth == 7 ? dateOfMonth = 0 : '';
 return dateOfMonth;
 },
 /**
 * 
 * 获取本月天数
 * @param {number} year 
 * @param {number} month 
 * @param {number} [day=0] 0为本月0最后一天的
 * @returns number 1-31
 */
 getNumOfDays(year, month, day = 0) {
 return new Date(year, month, day).getDate()
 },
 /**
 * 
 * 月份处理
 * @param {number} month 
 * @returns format month MM 1-12
 */
 formatMonth(month) {
 let monthStr = ''
 if (month > 12 || month < 1) {
  monthStr = Math.abs(month - 12) + ''
 } else {
  monthStr = month + ''
 }
 monthStr = `${monthStr.length > 1 ? '' : '0'}${monthStr}`
 return monthStr
 },
 formatDay(day) {
 return `${(day + '').length > 1 ? '' : '0'}${day}`
 }
}
Page(conf)

效果图

微信小程序自定义可滑动日历界面

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS版的date函数(和PHP的date函数一样)
May 12 Javascript
jquery+css3实现网页背景花瓣随机飘落特效
Aug 17 Javascript
JS实现先显示大图后自动收起显示小图的广告代码
Sep 04 Javascript
针对后台列表table拖拽比较实用的jquery拖动排序
Oct 10 Javascript
js实现的简练高效拖拽功能示例
Dec 21 Javascript
Javascript实现购物车功能的详细代码
May 08 Javascript
详解Vue-cli3 项目在安卓低版本系统和IE上白屏问题解决
Apr 14 Javascript
详解小程序开发经验:多页面数据同步
May 18 Javascript
vue history 模式打包部署在域名的二级目录的配置指南
Jul 02 Javascript
vue项目部署到nginx/tomcat服务器的实现
Aug 26 Javascript
使用jQuery实现掷骰子游戏
Oct 24 jQuery
微信小程序swiper左右扩展各显示一半代码实例
Dec 05 Javascript
10行代码实现微信小程序滑动tab切换
Dec 28 #Javascript
微信小程序实现复选框效果
Dec 28 #Javascript
6行代码实现微信小程序页面返回顶部效果
Dec 28 #Javascript
微信小程序下拉框组件使用方法详解
Dec 28 #Javascript
微信小程序实现星级评价效果
Dec 28 #Javascript
微信小程序实现日历效果
Dec 28 #Javascript
Mint UI实现A-Z字母排序的城市选择列表
Dec 28 #Javascript
You might like
PHP文件去掉PHP注释空格的函数分析(PHP代码压缩)
2013/07/02 PHP
浅谈php中include文件变量作用域
2015/06/18 PHP
Laravel框架实现的使用smtp发送邮件功能示例
2019/03/12 PHP
使用JS进行目录上传(相当于批量上传)
2010/12/05 Javascript
jquery命令汇总,方便使用jquery的朋友
2012/06/26 Javascript
使用jquery解析XML示例代码
2014/09/05 Javascript
js读写json文件实例代码
2014/10/21 Javascript
AngularJS 依赖注入详解和简单实例
2016/07/28 Javascript
jquery.Jcrop结合JAVA后台实现图片裁剪上传实例
2016/11/05 Javascript
ES6新特性二:Iterator(遍历器)和for-of循环详解
2017/04/20 Javascript
jquery插件canvaspercent.js实现百分比圆饼效果
2017/07/18 jQuery
bing Map 在vue项目中的使用详解
2018/04/09 Javascript
Vue组件全局注册实现警告框的实例详解
2018/06/11 Javascript
详解VUE自定义组件中用.sync修饰符与v-model的区别
2018/06/26 Javascript
Vue监听事件实现计数点击依次增加的方法
2018/09/26 Javascript
如何在Vue中抽离接口配置文件
2019/10/31 Javascript
使用 Vue-TCB 快速在 Vue 应用中接入云开发的方法
2020/02/10 Javascript
React 条件渲染最佳实践小结(7种)
2020/09/27 Javascript
python paramiko模块学习分享
2017/08/23 Python
pyQT5 实现窗体之间传值的示例
2019/06/20 Python
解决Pycharm 导入其他文件夹源码的2种方法
2020/02/12 Python
利用pyecharts读取csv并进行数据统计可视化的实现
2020/04/17 Python
基于python实现获取网页图片过程解析
2020/05/11 Python
python实现登录与注册系统
2020/11/30 Python
雅诗兰黛美国官网:Estee Lauder美国
2016/07/21 全球购物
泰国折扣酒店预订:Hotels2Thailand
2018/03/20 全球购物
物流管理毕业生自荐信范文
2014/03/15 职场文书
教师师德演讲稿
2014/05/06 职场文书
俄语专业毕业生求职信
2014/07/12 职场文书
六查六看自查报告
2014/10/14 职场文书
写给同学的新学期寄语
2015/02/27 职场文书
2015年教研组工作总结
2015/05/04 职场文书
nginx配置proxy_pass中url末尾带/与不带/的区别详解
2021/03/31 Servers
MySQL 数据恢复的多种方法汇总
2021/06/21 MySQL
python 中yaml文件用法大全
2021/07/04 Python