很快微信开发者平台

 找回密码
 注册
查看: 1498|回复: 1

微信小程序自定义日历

[复制链接]

3

主题

3

帖子

80

积分

新人求带

积分
80
 楼主| 发表于 2019-1-3 14:45:33 | 显示全部楼层 |阅读模式
微信小程序自定义日历,直接贴上代码了,可以拷贝到工程运行

效果图如下:

20181014165116133.png

代码有点多

WXML
  1. <view class='container'>
  2. <view class='month flex m-around'>
  3.     <view class='arrow' bindtap='prevMonth'>《 </view>
  4.     <view class='year-and-month'>
  5.         <picker mode="date" value="{{date}}" start="2015-09" end="2020-09" fields='month' bindchange="bindDateChange">
  6.         <view>
  7.             {{date}}
  8.         </view>
  9.         </picker>
  10.     </view>
  11.     <view class='arrow' bindtap='nextMonth'> 》</view>
  12. </view>
  13. <view class='calendar flex column s-center'>
  14.   <view class='week-row flex m-around'>
  15.     <view class='grid' wx:for="{{week}}" wx:key='item'>{{item}}</view>
  16.   </view>
  17.   <swiper class='swpier-box' circular="true" current="{{swiperIndex}}" bindchange='swiperChange'>
  18.     <swiper-item class='flex m-around days-table '>
  19.       <view wx:for="{{calendar.first}}" wx:for-item='x' wx:key='x.date'
  20.         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'>
  21.         <!-- <view>{{x.date === today?'今天':x.day}}</view> -->
  22.         <view>{{x.day}}</view>
  23.       </view>
  24.     </swiper-item>
  25.     <swiper-item class='flex m-around days-table '>
  26.       <view wx:for="{{calendar.second}}" wx:for-item='x' wx:key='x.date'
  27.         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'>
  28.         <!-- <view>{{x.date === today?'今天':x.day}}</view> -->
  29.         <view>{{x.day}}</view>
  30.       </view>
  31.     </swiper-item>
  32.     <swiper-item class='flex m-around days-table'>
  33.       <view wx:for="{{calendar.third}}" wx:for-item='x' wx:key='x.date'
  34.         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'>
  35.         <!-- <view>{{x.date === today?'今天':x.day}}</view> -->
  36.         <view>{{x.day}}</view>
  37.       </view>
  38.     </swiper-item>
  39.     <swiper-item class='flex m-around days-table '>
  40.       <view wx:for="{{calendar.fourth}}" wx:for-item='x' wx:key='x.date'
  41.         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'>
  42.         <!-- <view>{{x.date === today?'今天':x.day}}</view> -->
  43.         <view>{{x.day}}</view>
  44.       </view>
  45.     </swiper-item>
  46.   </swiper>
  47. </view>
  48. </view>
复制代码

CSS
  1. .container {
  2.   height: 100vh;

  3.   background-color: #393E44;
  4. }
  5. .days-table {
  6.   flex-wrap: wrap;
  7.   align-content: flex-start;
  8. }
  9. .calendar{
  10.   position: fixed;
  11.   z-index:10000;
  12.   background: #393E44;
  13.   
  14. }
  15. .grid {
  16.   width: 107.14rpx;
  17.   height: 100rpx;
  18.   text-align: center;
  19.   line-height: 100rpx;
  20.   font-size:.7rem;
  21.   color:#fff;
  22. }
  23. .today {
  24.   color: #88a1fd;
  25. }
  26. .grid view {
  27.   height:85rpx;
  28.   line-height: 85rpx;
  29.   width:85rpx;
  30. }
  31. .choice view{
  32.   border-radius: 50%;
  33.   background: #88a1fd;
  34.   background-position:center;
  35.   color: white;
  36. }
  37. /* 非本月日期 */
  38. .notCurrent {
  39.   color: silver;
  40. }
  41. .day-hover {
  42.   background: red;
  43. }
  44. .swpier-box {
  45.   height: 550rpx;
  46.   width: 100%;
  47. }
  48. .arrow {
  49.   width: 100rpx;
  50.   color: #88a1fd;
  51.   text-align: center;
  52. }
  53. .year-and-month{
  54.   color: #88a1fd;
  55. }

  56. .flex {
  57.   display: flex;
  58. }
  59. /* 轴向 */
  60. .column {
  61.   flex-direction: column;
  62. }
  63. /* 主轴方向 */
  64. .m-start {
  65.   justify-content: flex-start;
  66. }

  67. .m-end {
  68.   justify-content: flex-end;
  69. }

  70. .m-around {
  71.   justify-content: space-around;
  72. }
  73. .m-between {
  74.   justify-content: space-between;
  75. }
  76. .m-center {
  77.   justify-content: center;
  78. }
  79. /* 侧轴方向 */
  80. .s-start {
  81.   align-items: flex-start;
  82. }
  83. .s-end {
  84.   align-items: flex-end;
  85. }

  86. .s-around {
  87.   align-items: space-around;
  88. }
  89. .s-between {
  90.   align-items: space-between;
  91. }
  92. .s-center {
  93.   align-items: center;
  94. }
  95. JS

  96. 'use strict';

  97. let choose_year = null,
  98.   choose_month = null;
  99. const conf = {
  100.   data: {
  101.     day: '',
  102.     year: '',
  103.     month: '',
  104.     date: '2017-01',
  105.     today: '',
  106.     week: ['日', '一', '二', '三', '四', '五', '六'],
  107.     calendar: {
  108.       first: [],
  109.       second: [],
  110.       third: [],
  111.       fourth: []
  112.     },
  113.     swiperMap: ['first', 'second', 'third', 'fourth'],
  114.     swiperIndex: 1,
  115.     showCaldenlar: false
  116.   },
  117.   onLoad() {
  118.     const date = new Date()
  119.       , month = this.formatMonth(date.getMonth() + 1)
  120.       , year = date.getFullYear()
  121.       , day = this.formatDay(date.getDate())
  122.       , today = `${year}-${month}-${day}`
  123.     let calendar = this.generateThreeMonths(year, month)

  124.     this.setData({
  125.       calendar,
  126.       month,
  127.       year,
  128.       day,
  129.       today,
  130.       beSelectDate: today,
  131.       date: `${year}-${month}`
  132.     })
  133.   },

  134.   showCaldenlar() {
  135.     this.setData({
  136.       showCaldenlar: !this.data.showCaldenlar
  137.     })
  138.   },
  139.         /**
  140.          *
  141.          * 左右滑动
  142.          * @param {any} e
  143.          */
  144.   swiperChange(e) {
  145.     const lastIndex = this.data.swiperIndex
  146.       , currentIndex = e.detail.current
  147.     let flag = false
  148.       , { year, month, day, today, date, calendar, swiperMap } = this.data
  149.       , change = swiperMap[(lastIndex + 2) % 4]
  150.       , time = this.countMonth(year, month)
  151.       , key = 'lastMonth'

  152.     if (lastIndex > currentIndex) {
  153.       lastIndex === 3 && currentIndex === 0
  154.         ? flag = true
  155.         : null
  156.     } else {
  157.       lastIndex === 0 && currentIndex === 3
  158.         ? null
  159.         : flag = true
  160.     }
  161.     if (flag) {
  162.       key = 'nextMonth'
  163.     }

  164.     year = time[key].year
  165.     month = time[key].month
  166.     date = `${year}-${month}`
  167.     day = ''
  168.     if (today.indexOf(date) !== -1) {
  169.       day = today.slice(-2)
  170.     }

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

  174.     this.setData({
  175.       swiperIndex: currentIndex,
  176.       //文档上不推荐这么做,但是滑动并不会改变current的值,所以随之而来的计算会出错
  177.       year,
  178.       month,
  179.       date,
  180.       day,
  181.       calendar
  182.     })
  183.   },
  184.         /**
  185.          *
  186.          * 点击切换月份,生成本月视图以及临近两个月的视图
  187.          * @param {any} year
  188.          * @param {any} month
  189.          * @returns {object} calendar
  190.          */
  191.   generateThreeMonths(year, month) {
  192.     let { swiperIndex, swiperMap, calendar } = this.data
  193.       , thisKey = swiperMap[swiperIndex]
  194.       , lastKey = swiperMap[swiperIndex - 1 === -1 ? 3 : swiperIndex - 1]
  195.       , nextKey = swiperMap[swiperIndex + 1 === 4 ? 0 : swiperIndex + 1]
  196.       , time = this.countMonth(year, month)
  197.     delete calendar[lastKey]
  198.     calendar[lastKey] = this.generateAllDays(time.lastMonth.year, time.lastMonth.month)
  199.     delete calendar[thisKey]
  200.     calendar[thisKey] = this.generateAllDays(time.thisMonth.year, time.thisMonth.month)
  201.     delete calendar[nextKey]
  202.     calendar[nextKey] = this.generateAllDays(time.nextMonth.year, time.nextMonth.month)
  203.     return calendar
  204.   },
  205.   
  206.   bindDayTap(e) {
  207.     let { month, year } = this.data
  208.       , time = this.countMonth(year, month)
  209.       , tapMon = e.currentTarget.dataset.month
  210.       , day = e.currentTarget.dataset.day
  211.     if (tapMon == time.lastMonth.month) {
  212.       this.changeDate(time.lastMonth.year, time.lastMonth.month)
  213.     } else if (tapMon == time.nextMonth.month) {
  214.       this.changeDate(time.nextMonth.year, time.nextMonth.month)
  215.     } else {
  216.       this.setData({
  217.         day
  218.       })
  219.     }
  220.     let beSelectDate = e.currentTarget.dataset.date;
  221.     this.setData({
  222.       beSelectDate,
  223.       showCaldenlar: false
  224.     })
  225.   },
  226.   bindDateChange(e) {
  227.     if (e.detail.value === this.data.date) {
  228.       return
  229.     }

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

  232.     this.changeDate(year, month)
  233.   },
  234.   prevMonth(e) {
  235.     let { year, month } = this.data
  236.       , time = this.countMonth(year, month)
  237.     this.changeDate(time.lastMonth.year, time.lastMonth.month)
  238.   },
  239.   nextMonth(e) {
  240.     let { year, month } = this.data
  241.       , time = this.countMonth(year, month)
  242.     this.changeDate(time.nextMonth.year, time.nextMonth.month)
  243.   },
  244.         /**
  245.          *
  246.          * 直接改变日期
  247.          * @param {any} year
  248.          * @param {any} month
  249.          */
  250.   changeDate(year, month) {
  251.     let { day, today } = this.data
  252.       , calendar = this.generateThreeMonths(year, month)
  253.       , date = `${year}-${month}`
  254.     date.indexOf(today) === -1
  255.       ? day = '01'
  256.       : day = today.slice(-2)

  257.     this.setData({
  258.       calendar,
  259.       day,
  260.       date,
  261.       month,
  262.       year,
  263.     })
  264.   },
  265.         /**
  266.          *
  267.          * 月份处理
  268.          * @param {any} year
  269.          * @param {any} month
  270.          * @returns
  271.          */
  272.   countMonth(year, month) {
  273.     let lastMonth = {
  274.       month: this.formatMonth(parseInt(month) - 1)
  275.     }
  276.       , thisMonth = {
  277.         year,
  278.         month,
  279.         num: this.getNumOfDays(year, month)
  280.       }
  281.       , nextMonth = {
  282.         month: this.formatMonth(parseInt(month) + 1)
  283.       }

  284.     lastMonth.year = parseInt(month) === 1 && parseInt(lastMonth.month) === 12
  285.       ? `${parseInt(year) - 1}`
  286.       : year + ''
  287.     lastMonth.num = this.getNumOfDays(lastMonth.year, lastMonth.month)
  288.     nextMonth.year = parseInt(month) === 12 && parseInt(nextMonth.month) === 1
  289.       ? `${parseInt(year) + 1}`
  290.       : year + ''
  291.     nextMonth.num = this.getNumOfDays(nextMonth.year, nextMonth.month)
  292.     return {
  293.       lastMonth,
  294.       thisMonth,
  295.       nextMonth
  296.     }
  297.   },
  298.   currentMonthDays(year, month) {
  299.     const numOfDays = this.getNumOfDays(year, month)
  300.     return this.generateDays(year, month, numOfDays)
  301.   },
  302.         /**
  303.          * 生成上个月应显示的天
  304.          * @param {any} year
  305.          * @param {any} month
  306.          * @returns
  307.          */
  308.   lastMonthDays(year, month) {
  309.     const lastMonth = this.formatMonth(parseInt(month) - 1)
  310.       , lastMonthYear = parseInt(month) === 1 && parseInt(lastMonth) === 12
  311.         ? `${parseInt(year) - 1}`
  312.         : year
  313.       , lastNum = this.getNumOfDays(lastMonthYear, lastMonth) //上月天数
  314.     let startWeek = this.getWeekOfDate(year, month - 1, 1) //本月1号是周几
  315.       , days = []
  316.     if (startWeek == 7) {
  317.       return days
  318.     }

  319.     const startDay = lastNum - startWeek

  320.     return this.generateDays(lastMonthYear, lastMonth, lastNum, { startNum: startDay, notCurrent: true })
  321.   },
  322.         /**
  323.          * 生成下个月应显示天
  324.          * @param {any} year
  325.          * @param {any} month
  326.          * @returns
  327.          */
  328.   nextMonthDays(year, month) {
  329.     const nextMonth = this.formatMonth(parseInt(month) + 1)
  330.       , nextMonthYear = parseInt(month) === 12 && parseInt(nextMonth) === 1
  331.         ? `${parseInt(year) + 1}`
  332.         : year
  333.       , nextNum = this.getNumOfDays(nextMonthYear, nextMonth)  //下月天数
  334.     let endWeek = this.getWeekOfDate(year, month)                                                 //本月最后一天是周几
  335.       , days = []
  336.       , daysNum = 0
  337.     if (endWeek == 6) {
  338.       return days
  339.     } else if (endWeek == 7) {
  340.       daysNum = 6
  341.     } else {
  342.       daysNum = 6 - endWeek
  343.     }
  344.     return this.generateDays(nextMonthYear, nextMonth, daysNum, { startNum: 1, notCurrent: true })
  345.   },
  346.         /**
  347.          *
  348.          * 生成一个月的日历
  349.          * @param {any} year
  350.          * @param {any} month
  351.          * @returns Array
  352.          */
  353.   generateAllDays(year, month) {
  354.     let lastMonth = this.lastMonthDays(year, month)
  355.       , thisMonth = this.currentMonthDays(year, month)
  356.       , nextMonth = this.nextMonthDays(year, month)
  357.       , days = [].concat(lastMonth, thisMonth, nextMonth)
  358.     return days
  359.   },
  360.         /**
  361.          *
  362.          * 生成日详情
  363.          * @param {any} year
  364.          * @param {any} month
  365.          * @param {any} daysNum
  366.          * @param {boolean} [option={
  367.          *                 startNum:1,
  368.          *                 grey: false
  369.          *         }]
  370.          * @returns Array 日期对象数组
  371.          */
  372.   generateDays(year, month, daysNum, option = {
  373.     startNum: 1,
  374.     notCurrent: false
  375.   }) {
  376.     const weekMap = ['一', '二', '三', '四', '五', '六', '日']
  377.     let days = []
  378.     for (let i = option.startNum; i <= daysNum; i++) {
  379.       let week = weekMap[new Date(year, month - 1, i).getUTCDay()]
  380.       let day = this.formatDay(i)
  381.       days.push({
  382.         date: `${year}-${month}-${day}`,
  383.         event: false,
  384.         day,
  385.         week,
  386.         month,
  387.         year
  388.       })
  389.     }
  390.     return days
  391.   },
  392.         /**
  393.          *
  394.          * 获取指定月第n天是周几                |
  395.          * 9月第1天: 2017, 08, 1 |
  396.          * 9月第31天:2017, 09, 0
  397.          * @param {any} year
  398.          * @param {any} month
  399.          * @param {number} [day=0] 0为最后一天,1为第一天
  400.          * @returns number 周 1-7,
  401.          */
  402.   getWeekOfDate(year, month, day = 0) {
  403.     let dateOfMonth = new Date(year, month, 0).getUTCDay() + 1;
  404.     dateOfMonth == 7 ? dateOfMonth = 0 : '';
  405.     return dateOfMonth;
  406.   },
  407.         /**
  408.          *
  409.          * 获取本月天数
  410.          * @param {number} year
  411.          * @param {number} month
  412.          * @param {number} [day=0] 0为本月0最后一天的
  413.          * @returns number 1-31
  414.          */
  415.   getNumOfDays(year, month, day = 0) {
  416.     return new Date(year, month, day).getDate()
  417.   },
  418.         /**
  419.          *
  420.          * 月份处理
  421.          * @param {number} month
  422.          * @returns format month MM 1-12
  423.          */
  424.   formatMonth(month) {
  425.     let monthStr = ''
  426.     if (month > 12 || month < 1) {
  427.       monthStr = Math.abs(month - 12) + ''
  428.     } else {
  429.       monthStr = month + ''
  430.     }
  431.     monthStr = `${monthStr.length > 1 ? '' : '0'}${monthStr}`
  432.     return monthStr
  433.   },
  434.   formatDay(day) {
  435.     return `${(day + '').length > 1 ? '' : '0'}${day}`
  436.   }
  437. }
  438. Page(conf)
复制代码


回复

使用道具 举报

0

主题

1327

帖子

1万

积分

S2

积分
15653
发表于 2019-1-4 09:33:25 | 显示全部楼层
6666666666666
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|手机版|小黑屋|很快微信开发者平台 ( 京ICP备2021012841号 )

GMT+8, 2021-6-24 15:18 , Processed in 0.032005 second(s), 24 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表