calendar.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. const DAY_NUM = 42
  2. const WEEK_DAY_NUM = 7
  3. const DATE_CHECK = /^(\d{4})-(\d{2})-(\d{2})$/
  4. Component({
  5. externalClasses: ['calendar-class'],
  6. properties: {
  7. defaultSelectDate: {
  8. type: String,
  9. value: ''
  10. },
  11. mode: {
  12. type: String,
  13. value: ''
  14. },
  15. showToday: {
  16. type: Boolean,
  17. value: true
  18. }
  19. },
  20. data: {
  21. pickDate: '',
  22. pickDateDisplay: '',
  23. tMonthFirstDayWeek: 0,
  24. allDays: [],
  25. selectedDate: '',
  26. today: '',
  27. dateRange: []
  28. },
  29. ready() {
  30. const now = new Date()
  31. if (!DATE_CHECK.test(this.data.defaultSelectDate)) {
  32. this.setData({
  33. defaultSelectDate: ''
  34. })
  35. }
  36. this.setData({
  37. selectedDate: this.data.defaultSelectDate || this.parseTime(now, '{y}-{m}-{d}'),
  38. today: this.parseTime(now, '{y}-{m}-{d}')
  39. })
  40. this.setCalendar(this.parseTime(now, '{y}-{m}'))
  41. },
  42. methods: {
  43. setCalendar(dateStr) {
  44. const self = this
  45. const selectDate = new Date(dateStr)
  46. const pickDate = self.parseTime(selectDate, '{y}-{m}')
  47. const dateSplit = dateStr.split('-')
  48. const thisYear = dateSplit[0]
  49. const thisMonth = dateSplit[1]
  50. const tempWeek = new Date(`${self.parseTime(selectDate, '{y}-{m}-')}01`).getDay()
  51. const tMonthFirstDayWeek = tempWeek === 0 ? WEEK_DAY_NUM : tempWeek
  52. const lastMonthOrigin = [...Array(self.getMonthDayNum(selectDate.getFullYear(), selectDate.getMonth())).keys()]
  53. const thisMonthOrigin = [...Array(self.getMonthDayNum(selectDate.getFullYear(), selectDate.getMonth() + 1)).keys()]
  54. const nextMonthOrigin = [...Array(self.getMonthDayNum(selectDate.getFullYear(), selectDate.getMonth() + 2)).keys()]
  55. const lastMonthFinal = [...lastMonthOrigin].splice(lastMonthOrigin.length - (tMonthFirstDayWeek - 1), lastMonthOrigin.length)
  56. const nextMonthFinal = [...nextMonthOrigin].splice(0, DAY_NUM - lastMonthFinal.length - thisMonthOrigin.length)
  57. self.setData({
  58. pickDate,
  59. pickDateDisplay: self.parseTime(selectDate, '{y}年{m}月'),
  60. tMonthFirstDayWeek,
  61. allDays: [
  62. ...this.mapMonth(lastMonthFinal, thisYear, Number(thisMonth) - 1, pickDate),
  63. ...this.mapMonth(thisMonthOrigin, thisYear, Number(thisMonth), pickDate),
  64. ...this.mapMonth(nextMonthFinal, thisYear, Number(thisMonth) + 1, pickDate)
  65. ]
  66. })
  67. },
  68. mapMonth(dayArr, year, month, pickDate = null) {
  69. const thisMonthNum = pickDate && Number(pickDate.split('-')[1])
  70. return dayArr.map(item => {
  71. const date = `${year}-${month < 10 ? `0${month}` : month}-${(item + 1) < 10 ? `0${item + 1}` : item + 1}`
  72. const week = new Date(date).getDay()
  73. return {
  74. dateNumber: item + 1,
  75. date,
  76. week: week === 0 ? 7 : week,
  77. position: thisMonthNum === month ? '' : month === thisMonthNum - 1 ? 'next-month' : 'pre-month'
  78. }
  79. })
  80. },
  81. bindPickDateChange(event) {
  82. const { value } = event.detail
  83. this.setData({
  84. pickDate: value,
  85. pickDateDisplay: this.parseTime(value, '{y}年{m}月')
  86. })
  87. this.setCalendar(value)
  88. this.triggerEvent('onPickDateChange', value)
  89. },
  90. // 获取月天数
  91. getMonthDayNum(year, month) {
  92. const d = new Date(year, month, 0)
  93. return d.getDate()
  94. },
  95. control(event) {
  96. const { mode } = event.currentTarget.dataset
  97. const { pickDate } = this.data
  98. let dateArr = pickDate.split('-')
  99. let oldMonth = Number(dateArr[1])
  100. let oldYear = Number(dateArr[0])
  101. let newDate = ''
  102. switch(mode) {
  103. case 'pre':
  104. newDate = oldMonth === 1 ? `${oldYear - 1}-12` : `${oldYear}-${oldMonth - 1 < 10 ? `0${oldMonth - 1}` : oldMonth - 1}`
  105. break;
  106. case 'reset':
  107. newDate = this.data.defaultSelectDate || new Date()
  108. if (this.data.mode === 'range') {
  109. this.setData({
  110. selectedDate: newDate,
  111. dateRange: []
  112. })
  113. } else {
  114. this.setData({
  115. selectedDate: this.parseTime(newDate, '{y}-{m}-{d}')
  116. })
  117. }
  118. break;
  119. case 'next':
  120. newDate = oldMonth === 12 ? `${oldYear + 1}-01` : `${oldYear}-${oldMonth + 1 < 10 ? `0${oldMonth + 1}` : oldMonth + 1}`
  121. break;
  122. }
  123. const timeParse = this.parseTime(new Date(newDate), '{y}-{m}')
  124. this.setCalendar(timeParse)
  125. if (mode !== 'reset' && this.data.mode === 'range') {
  126. this.findRange(this.data.dateRange)
  127. }
  128. this.triggerEvent('onControl', {
  129. mode,
  130. newDate: timeParse
  131. })
  132. wx.vibrateShort()
  133. },
  134. onPickDay(event) {
  135. const { day } = event.currentTarget.dataset
  136. const { mode } = this.data
  137. let dateRange = [...this.data.dateRange]
  138. if (mode === 'range') {
  139. this.setData({
  140. selectedDate: ''
  141. })
  142. if (!dateRange[0]) {
  143. dateRange.push(day.date)
  144. this.setData({
  145. dateRange
  146. })
  147. } else if (!dateRange[1]) {
  148. dateRange.push(day.date)
  149. dateRange.sort((a, b) => a > b ? 1 : -1)
  150. this.setData({
  151. dateRange
  152. })
  153. this.findRange(dateRange)
  154. this.triggerEvent('onRangePick', dateRange)
  155. } else {
  156. this.setData({
  157. dateRange: [day.date]
  158. })
  159. this.findRange([day.date])
  160. }
  161. } else {
  162. this.setData({
  163. selectedDate: day.date
  164. })
  165. this.triggerEvent('onPickDay', day)
  166. }
  167. },
  168. // 找出range内的日期
  169. findRange(dateRange) {
  170. const minTimeStamp = Date.parse(dateRange[0])
  171. const maxTimeStamp = Date.parse(dateRange[1])
  172. let allDays = [...this.data.allDays]
  173. allDays.forEach(item => {
  174. const parseDate = Date.parse(item.date)
  175. item[`inRange`] = dateRange.length === 1 ? false : parseDate < maxTimeStamp && parseDate > minTimeStamp
  176. })
  177. this.setData({
  178. allDays
  179. })
  180. },
  181. parseTime(time, cFormat) {
  182. if (arguments.length === 0) {
  183. return null
  184. }
  185. const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  186. let date
  187. if (typeof time === 'object') {
  188. date = time
  189. } else {
  190. if (('' + time).length === 10) time = parseInt(time) * 1000
  191. date = new Date(time)
  192. }
  193. const formatObj = {
  194. y: date.getFullYear(),
  195. m: date.getMonth() + 1,
  196. d: date.getDate(),
  197. h: date.getHours(),
  198. i: date.getMinutes(),
  199. s: date.getSeconds(),
  200. a: date.getDay()
  201. }
  202. const timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
  203. let value = formatObj[key]
  204. if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]
  205. if (result.length > 0 && value < 10) {
  206. value = '0' + value
  207. }
  208. return value || 0
  209. })
  210. return timeStr
  211. }
  212. }
  213. })