Dater.js
1 /** 2 * 换算某月的上个月,下月,本月的月信息,日历写死展示42天, 3 * 可以通过更改: 4 * var nextlen = 42 - (prem.length + getMonthDay[m - 1]); 42改成35 5 * 上月和下月不显示数据可以可以注释掉相应月的赋值代码,修改此对象: 6 * this.monthDays = { 7 preMonthDays: prem, //上月的天 8 thisMonthDays: im, //本月的天 9 nextMonthDays: nextm, //下月的天 10 day: d, 11 month: m, 12 year: y 13 } 14 */ 15 export default function Dater (y, m, d) { 16 var date = new Date() 17 18 // 获取年,月,天 19 var y = y || date.getFullYear(), 20 m = m || date.getMonth() + 1, 21 d = d || date.getDate() 22 23 // 是否为闰年,闰年能被4和400整除,不能被100整除 24 var isLeapYear = function (years) { 25 return !!((years % 4 == 0 && years % 100 !== 0) || (years % 400 === 0)) 26 } 27 28 // 获取月的一号是星期几, 0是星期日 29 var getFirstDay = function (y, m, d) { 30 var d = new Date(y, m, d) 31 d.setDate(1) 32 return d.getDay() 33 } 34 35 // 每月有多少天,一年12月的天数 36 var getMonthDay = [31, isLeapYear(y) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 37 38 // prem 上月的天信息,im本月的天信息, nextm下个月的天信息, lastmd上个月的天数 39 var prem = [], im = [], nextm = [], lastmd = getMonthDay[m - 1 - 1] 40 41 //设置上月的天数信息 42 // 该月的1号是不是周日, 43 if (getFirstDay(y, m - 1, d) === 0) { 44 for (var i = 6; i >= 0; i--) { 45 prem[6 - i] = lastmd - i 46 } 47 } else { 48 for (var i = getFirstDay(y, m - 1, d); i > 0; i--) { 49 prem[getFirstDay(y, m - 1, d) - i] = lastmd - i + 1 50 } 51 } 52 53 // 设置本月的天数信息 54 for (var i = 0; i < getMonthDay[m - 1]; i++) { 55 im[i] = i + 1 56 } 57 58 // 设置下月的天信息 59 // 日历展示42天 60 var nextlen = 42 - (prem.length + getMonthDay[m - 1]) 61 for (var i = 0; i < nextlen; i++) { 62 nextm[i] = i + 1 63 } 64 65 66 if (isNaN(prem[0])) { 67 for (let i = 0; i < prem.length; i++) { 68 prem[i] = 31 - prem.length + i + 1 69 } 70 } 71 72 73 this.monthDays = { 74 preMonthDays: prem, //上月的天 75 thisMonthDays: im, //本月的天 76 nextMonthDays: nextm, //下月的天 77 day: d, 78 month: m, 79 year: y 80 } 81 82 // 没有看明白此算法的作用,在日历中没有使用this.weekDays数据 83 var arr = [] 84 for (var i = 0; i < 7; i++) { 85 var weekDate = new Date() 86 weekDate.setFullYear(y) 87 weekDate.setMonth(m - 1) 88 weekDate.setDate(d - 1) 89 var weekday = weekDate.getDay() // 获取星期几0-6 90 var newday = weekDate.getDate() + 1 - weekday + i // 91 weekDate.setDate(newday - 1) 92 arr.push({ 93 year: weekDate.getFullYear(), 94 month: weekDate.getMonth() + 1, 95 day: weekDate.getDate() + 1 96 }) 97 } 98 this.weekDays = { 99 data: arr, 100 day: d, 101 month: m, 102 year: y 103 } 104 // var array = [] 105 // for (var i = 0; i < prem.length; i++) { 106 // array.push(`${y}-${m - 1}-${prem[i]}`) 107 // } 108 // for (var i = 0; i < im.length; i++) { 109 // array.push(`${y}-${m}-${im[i]}`) 110 // } 111 // for (var i = 0; i < nextm.length; i++) { 112 // array.push(`${y}-${m + 1}-${nextm[i]}`) 113 // } 114 // console.log(array) 115 // var arrayIndex = 0; 116 // for (var i = 0; i < array.length; i++) { 117 // if(m === Number(array[i].split('-')[1]) && d === Number(array[i].split('-')[2])) { 118 // arrayIndex = i 119 // break 120 // } 121 // } 122 }; 123 124 Dater.change = function (anchor, type, time) { 125 var date = new Date() 126 date.setFullYear(anchor.year, anchor.month - 1, anchor.day) 127 switch (type) { 128 case 'y': { 129 date.setFullYear(date.getFullYear() + time) 130 break 131 } 132 case 'm': { 133 date.setMonth(date.getMonth() + time) 134 break 135 } 136 case 'w': { 137 date.setDate(date.getDate() + time * 7) 138 break 139 } 140 case 'd': { 141 date.setDate(date.getDate() + time) 142 break 143 } 144 } 145 return { 146 year: date.getFullYear(), 147 month: date.getMonth() + 1, 148 day: date.getDate() 149 } 150 } 151 152 Dater.getTodayAnchor = function () { 153 var date = new Date() 154 return { 155 year: date.getFullYear(), 156 month: date.getMonth() + 1, 157 day: date.getDate() 158 } 159 } 160 Dater.AnchorToDayString = function (anchor) { 161 // return '' + anchor.year + (anchor.month < 10 ? '0' : '') + anchor.month + (anchor.day < 10 ? '0' : '') + anchor.day 162 // console.log( `${anchor.year}/${anchor.month < 10 ? '0': ''}${anchor.month}/${anchor.day < 10 ? '0' : ''}${anchor.day}`) 163 return `${anchor.year}/${anchor.month < 10 ? '0': ''}${anchor.month}/${anchor.day < 10 ? '0' : ''}${anchor.day}` 164 }
Calendar.wx

1 <script> 2 import props from './props.js' 3 import Dater from '../../libs/date.js' 4 import OTS from '../../libs/objectToStyle.js' 5 var moment = require('moment') 6 7 export default { 8 config: { 9 usingComponents: { } 10 }, 11 behaviors: [props], 12 data: { 13 selectItem: {}, 14 dayMap: {}, 15 monthsArray: [], 16 oldItem: undefined, 17 scrollTop: 0, 18 oldRangeLeftItem: undefined, 19 oldRangeRightItem: undefined, 20 heightCount: 50, 21 monthSwiperIndex: 0, 22 myItem: undefined 23 }, 24 attached () { 25 console.log('attached') 26 27 28 }, 29 ready () { 30 this.reAttached () 31 32 console.log(this.data.dayMap) 33 34 }, 35 methods: { 36 reAttached () { 37 38 // 获取开始月到结束月之前所有的月信息 39 this.data.monthsArray.splice(0, this.data.monthsArray.length) 40 let startMonthAnchor 41 let endMonthAnchor 42 if (isNaN( Number(this.data.dateRange[0]))) { // 字符串 43 startMonthAnchor = this.data.dateRange[0] + '/01' 44 endMonthAnchor = this.data.dateRange[1] + '/01' 45 } else { 46 startMonthAnchor = moment().subtract(this.data.dateRange[0], 'months').format('YYYY/MM') + '/01' 47 endMonthAnchor = moment().add(this.data.dateRange[1], 'months').format('YYYY/MM') + '/01' 48 } 49 50 console.log(startMonthAnchor, endMonthAnchor) 51 52 for (let i = 0;; i++) { 53 let year = moment(startMonthAnchor).year() //年 54 let month = moment(startMonthAnchor).month() + 1 //月,月在date中用0-11表示十二个月 55 let day = moment(startMonthAnchor).date() //天 56 57 let startMonthDater = new Dater(year, month, day).monthDays // Dater使用的是正常月份 58 let monthArray = this.getMonthArray(startMonthDater, i) 59 monthArray.monthIndex = i 60 this.data.monthsArray.push(monthArray) 61 if (moment(startMonthAnchor).isSame(endMonthAnchor, 'month')) { 62 break 63 } 64 startMonthAnchor = moment(startMonthAnchor).add(1, 'month') 65 } 66 67 if (this.data.value) { 68 if (typeof this.data.value === 'string') { 69 let dIndex = this.momentTransToItem(moment(this.data.value)).dayIndex 70 let mIndex = this.momentTransToItem(moment(this.data.value)).monthIndex 71 this.selectSingle(mIndex, dIndex) 72 } else { 73 let dIndex = this.momentTransToItem(moment(this.data.value[0])).dayIndex 74 let mIndex = this.momentTransToItem(moment(this.data.value[0])).monthIndex 75 this.selectRange(mIndex, dIndex, true) 76 mIndex = this.momentTransToItem(moment(this.data.value[1])).monthIndex 77 dIndex = this.momentTransToItem(moment(this.data.value[1])).dayIndex 78 this.selectRange(mIndex, dIndex) 79 } 80 } 81 this.setData({ 82 monthsArray: this.data.monthsArray, 83 monthTitleStyle: OTS(this.data.monthTitleStyle), 84 calendarWrapStyle: OTS(this.calendarWrapStyleObj()) 85 }) 86 // }, 3000); 87 88 }, 89 changeHandler (e) { 90 let index = e.detail.current 91 // console.log() 92 this.triggerEvent('monthchange', 93 `${this.data.monthsArray[index].year}/${this.data.monthsArray[index].month >= 10 ? '' :'0'}${this.data.monthsArray[index].month}`) 94 }, 95 calendarWrapStyleObj () { 96 let style = {} 97 style.height = this.data.height + 'px' 98 return style 99 }, 100 itemTransToMoment (item) { 101 if (item.day) { 102 return moment(`${item.year}/${item.month}/${item.day}`) 103 } else { 104 return moment(`${item.year}/${item.month}`) 105 } 106 }, 107 momentTransToItem (moment) { 108 for (let i = 0; i < this.data.monthsArray.length; i++) { 109 for (let j = 0; j < this.data.monthsArray[i].data.length; j++) { 110 if ( 111 this.data.monthsArray[i].data[j].isThisMonth && 112 moment.isSame(this.itemTransToMoment(this.data.monthsArray[i].data[j]))) { 113 return this.data.monthsArray[i].data[j] 114 } 115 } 116 } 117 }, 118 inRangeSelect (rightItem, startI, endI, select) { 119 for (let i = startI; i <= endI ; i++) { 120 for (let j = 0; j < this.data.monthsArray[startI].data.length; j++) { 121 if (this.data.monthsArray[i].data[j].isThisMonth && 122 this.itemTransToMoment(this.data.monthsArray[i].data[j]).isAfter(this.itemTransToMoment(this.data.oldRangeLeftItem), 'day') && 123 this.itemTransToMoment(this.data.monthsArray[i].data[j]).isBefore(this.itemTransToMoment(rightItem), 'day')) { 124 if (select) { 125 this.data.monthsArray[i].data[j].isInRange = true 126 } else { 127 this.data.monthsArray[i].data[j].isInRange = false 128 } 129 } 130 if (this.itemTransToMoment(this.data.monthsArray[i].data[j]).isSame(this.itemTransToMoment(rightItem), 'day')) { 131 break 132 } 133 } 134 } 135 }, 136 selectRange (mIndex, dIndex, trans) { 137 let selectItem = this.data.monthsArray[mIndex].data[dIndex] 138 let selectMoment = this.itemTransToMoment(selectItem) 139 if (selectItem.isPastDay && this.data.disablePastDays) { 140 this.triggerEvent('failed') 141 return 142 } 143 if (selectItem.isForeDay && this.data.disableForeDays) { 144 this.triggerEvent('failed') 145 return 146 } 147 if (selectItem.isToday && !this.data.canSelectToday) { 148 this.triggerEvent('failed') 149 return 150 } 151 if (!this.data.oldRangeLeftItem && !this.data.oldRangeRightItem) { // 两边都没有 152 selectItem.isRangeLeft = true // 变颜色 153 this.data.oldRangeLeftItem = selectItem // 老东西 154 this.triggerEvent('selectedstart', selectItem.value) 155 } else if (this.data.oldRangeLeftItem, !this.data.oldRangeRightItem) { //左有右没有 156 // maxRange选取 157 if (this.data.maxRange) { 158 if (this.itemTransToMoment(this.data.oldRangeLeftItem).add(this.data.maxRange, 'day').isBefore(selectMoment,'day')) { 159 this.triggerEvent('failed') 160 return 161 } 162 } 163 if (this.itemTransToMoment(this.data.oldRangeLeftItem).isAfter(selectMoment, 'day')) { // 如果选择在之前 164 // this.data.oldRangeLeftItem = this. 165 this.data.oldRangeLeftItem.isRangeLeft = false 166 selectItem.isRangeLeft = true // 变颜色 167 this.data.oldRangeLeftItem = selectItem 168 this.triggerEvent('selectedstart', selectItem.value) 169 } else if (this.itemTransToMoment(this.data.oldRangeLeftItem).isBefore(selectMoment, 'day')) { // 如果选择在之后 170 171 selectItem.isRangeRight = true // 变颜色 172 this.data.oldRangeRightItem = selectItem // 老东西 173 let startI = this.data.oldRangeLeftItem.monthIndex 174 let endI = selectItem.monthIndex 175 this.inRangeSelect(selectItem, startI, endI, true) 176 this.triggerEvent('selectedend', selectItem.value) 177 } else { 178 selectItem.isRangeLeft = false // 变颜色 179 this.data.oldRangeLeftItem = undefined 180 } 181 } else { //如果都有 182 let startI = this.data.oldRangeLeftItem.monthIndex 183 let endI = this.data.oldRangeRightItem.monthIndex 184 this.inRangeSelect(this.data.oldRangeRightItem, startI, endI, false) 185 this.data.oldRangeLeftItem.isRangeLeft = false 186 this.data.oldRangeRightItem.isRangeRight = false 187 this.data.oldRangeRightItem = undefined 188 selectItem.isRangeLeft = true // 变颜色 189 this.data.oldRangeLeftItem = selectItem // 老东西 190 this.triggerEvent('selectedstart', selectItem.value) 191 } 192 if (trans) { 193 this.setData({ 194 monthSwiperIndex:mIndex 195 }) 196 } 197 }, 198 selectSingle (mIndex, dIndex) { 199 let selectItem = this.data.monthsArray[mIndex].data[dIndex] 200 201 if (selectItem.isPastDay && this.data.disablePastDays) { 202 this.triggerEvent('failed') 203 return 204 } 205 if (selectItem.isForeDay && this.data.disableForeDays) { 206 this.triggerEvent('failed') 207 return 208 } 209 if (selectItem.isToday && !this.data.canSelectToday) { 210 this.triggerEvent('failed') 211 return 212 } 213 214 if (this.data.oldItem) { 215 this.data.oldItem.isClicked = false 216 } 217 this.data.monthsArray[mIndex].data[dIndex].isClicked = true 218 219 220 this.data.oldItem = this.data.monthsArray[mIndex].data[dIndex] 221 222 223 this.data.selectItem = this.data.oldItem 224 this.setData({ 225 monthSwiperIndex:mIndex, 226 myItem: this.data.selectItem, 227 oldItem: this.data.oldItem 228 }) 229 this.triggerEvent('change', selectItem.value) 230 }, 231 touchStartHandler (e) { 232 233 console.time('a') 234 let mIndex = e.currentTarget.dataset.monthIndex 235 let dIndex = e.currentTarget.dataset.dayIndex 236 let selectItem = this.data.monthsArray[mIndex].data[dIndex] 237 if (selectItem.isThisMonth === false) { 238 return 239 } 240 if (this.data.selectRangeMode) { 241 this.selectRange(mIndex, dIndex) 242 } else { 243 this.selectSingle(mIndex, dIndex) 244 } 245 // this.setData({ 246 // monthsArray: this.data.monthsArray 247 // }) 248 console.timeEnd('a') 249 }, 250 getMonthArray (date, monthIndex) { 251 let monthArray = {} 252 let lineCount = 0 253 var count = 0 254 monthArray.data = [] 255 monthArray.year = date.year 256 monthArray.month = date.month 257 for (let i = 0; i < date.preMonthDays.length; i++) { 258 let obj = {} 259 obj.day = date.preMonthDays[i] 260 if (date.month === 1) { 261 obj.month = 12 262 obj.year = date.year - 1 263 } else { 264 obj.month = date.month - 1 265 obj.year = date.year 266 } 267 obj.value = `${obj.year}/${obj.month < 10 ? '0' : ''}${obj.month}/${obj.day < 10 ? '0' : ''}${obj.day}` 268 269 270 obj.isThisMonth = false 271 obj.isClicked = false 272 obj.isRangeLeft = false 273 obj.isRangeRight = false 274 obj.isInRange = false 275 obj.monthIndex = monthIndex 276 obj.dayIndex = count 277 this.data.dayMap[obj.value] = obj 278 if ([0, 6].indexOf((moment(obj.value).weekday())) !== -1) { 279 obj.isHoliday = true 280 } 281 monthArray.data.push(obj) 282 count++ 283 } 284 for (let i = 0; i < date.thisMonthDays.length; i++) { 285 let obj = {} 286 obj.day = date.thisMonthDays[i] 287 obj.month = date.month 288 obj.year = date.year 289 obj.isThisMonth = true 290 obj.isClicked = false 291 obj.isRangeLeft = false 292 obj.isRangeRight = false 293 obj.isInRange = false 294 obj.monthIndex = monthIndex 295 obj.dayIndex = count 296 obj.value = `${obj.year}/${obj.month < 10 ? '0' : ''}${obj.month}/${obj.day < 10 ? '0' : ''}${obj.day}` 297 if ([0, 6].indexOf((moment(obj.value).weekday())) !== -1) { 298 obj.isHoliday = true 299 } 300 if (moment(`${obj.year}/${obj.month}/${obj.day}`).isBefore(moment(), 'day')) { 301 obj.isPastDay = true 302 obj.isForeDay = true 303 obj.isToday = false 304 } else if (moment(`${obj.year}/${obj.month}/${obj.day}`).isAfter(moment(), 'day')) { 305 obj.isPastDay = false 306 obj.isForeDay = true 307 obj.isToday = false 308 } else { 309 obj.isPastDay = false 310 obj.isForeDay = false 311 obj.isToday = true 312 } 313 monthArray.data.push(obj) 314 count++ 315 this.data.dayMap[obj.value] = obj 316 } 317 // if (date.nextMonthDays.length >= 7) { 318 // date.nextMonthDays.splice(date.nextMonthDays.length - 7, 7) 319 // lineCount++ 320 // } 321 322 for (let i = 0; i < date.nextMonthDays.length; i++) { 323 let obj = {} 324 obj.day = date.nextMonthDays[i] 325 326 if (date.month === 12) { 327 obj.month = 1 328 obj.year = date.year + 1 329 } else { 330 obj.month = date.month + 1 331 obj.year = date.year 332 } 333 obj.isThisMonth = false 334 obj.isClicked = false 335 obj.isRangeLeft = false 336 obj.isRangeRight = false 337 obj.isInRange = false 338 obj.monthIndex = monthIndex 339 obj.dayIndex = count 340 obj.value = `${obj.year}/${obj.month < 10 ? '0' : ''}${obj.month}/${obj.day < 10 ? '0' : ''}${obj.day}` 341 if ([0, 6].indexOf((moment(obj.value).weekday())) !== -1) { 342 obj.isHoliday = true 343 } 344 monthArray.data.push(obj) 345 count++ 346 this.data.dayMap[obj.value] = obj 347 348 } 349 monthArray.positionY = this.data.heightCount 350 351 352 monthArray.value = `${date.year}/${date.month > 10 ? '' : '0'}${date.month}` 353 354 355 356 if (lineCount === 0) { 357 monthArray.monthHeight = 350 358 } else if (lineCount === 1) { 359 monthArray.monthHeight = 300 360 } else { 361 monthArray.monthHeight = 250 362 } 363 this.data.heightCount += monthArray.monthHeight 364 return monthArray 365 }, 366 } 367 } 368 369 </script>