index.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. import Week from './func/week'
  2. import { Logger, Slide, GetDate, initialTasks } from './func/utils'
  3. import initCalendar, {
  4. jump,
  5. getCurrentYM,
  6. whenChangeDate,
  7. renderCalendar,
  8. whenMulitSelect,
  9. whenSingleSelect,
  10. whenChooseArea,
  11. getCalendarDates
  12. } from './main.js'
  13. const slide = new Slide()
  14. const logger = new Logger()
  15. const getDate = new GetDate()
  16. Component({
  17. options: {
  18. styleIsolation: 'apply-shared',
  19. multipleSlots: true // 在组件定义时的选项中启用多slot支持
  20. },
  21. properties: {
  22. calendarConfig: {
  23. type: Object,
  24. value: {}
  25. }
  26. },
  27. data: {
  28. handleMap: {
  29. prev_year: 'chooseYear',
  30. prev_month: 'chooseMonth',
  31. next_month: 'chooseMonth',
  32. next_year: 'chooseYear'
  33. }
  34. },
  35. lifetimes: {
  36. attached: function() {
  37. this.initComp()
  38. },
  39. detached: function() {
  40. initialTasks.flag = 'finished'
  41. initialTasks.tasks.length = 0
  42. }
  43. },
  44. methods: {
  45. initComp() {
  46. const calendarConfig = this.setDefaultDisableDate()
  47. this.setConfig(calendarConfig)
  48. },
  49. setDefaultDisableDate() {
  50. const calendarConfig = this.properties.calendarConfig || {}
  51. if (calendarConfig.disableMode && !calendarConfig.disableMode.date) {
  52. calendarConfig.disableMode.date = getDate.toTimeStr(getDate.todayDate())
  53. }
  54. return calendarConfig
  55. },
  56. setConfig(config) {
  57. if (config.markToday && typeof config.markToday === 'string') {
  58. config.highlightToday = true
  59. }
  60. config.theme = config.theme || 'default'
  61. this.weekMode = config.weekMode
  62. this.setData(
  63. {
  64. calendarConfig: config
  65. },
  66. () => {
  67. initCalendar(this, config)
  68. }
  69. )
  70. },
  71. chooseDate(e) {
  72. const { type } = e.currentTarget.dataset
  73. if (!type) return
  74. const methodName = this.data.handleMap[type]
  75. this[methodName](type)
  76. },
  77. chooseYear(type) {
  78. const { curYear, curMonth } = this.data.calendar
  79. if (!curYear || !curMonth) return logger.warn('异常:未获取到当前年月')
  80. if (this.weekMode) {
  81. return console.warn('周视图下不支持点击切换年月')
  82. }
  83. let newYear = +curYear
  84. let newMonth = +curMonth
  85. if (type === 'prev_year') {
  86. newYear -= 1
  87. } else if (type === 'next_year') {
  88. newYear += 1
  89. }
  90. this.render(curYear, curMonth, newYear, newMonth)
  91. },
  92. chooseMonth(type) {
  93. const { curYear, curMonth } = this.data.calendar
  94. if (!curYear || !curMonth) return logger.warn('异常:未获取到当前年月')
  95. if (this.weekMode) return console.warn('周视图下不支持点击切换年月')
  96. let newYear = +curYear
  97. let newMonth = +curMonth
  98. if (type === 'prev_month') {
  99. newMonth = newMonth - 1
  100. if (newMonth < 1) {
  101. newYear -= 1
  102. newMonth = 12
  103. }
  104. } else if (type === 'next_month') {
  105. newMonth += 1
  106. if (newMonth > 12) {
  107. newYear += 1
  108. newMonth = 1
  109. }
  110. }
  111. this.render(curYear, curMonth, newYear, newMonth)
  112. },
  113. render(curYear, curMonth, newYear, newMonth) {
  114. whenChangeDate.call(this, {
  115. curYear,
  116. curMonth,
  117. newYear,
  118. newMonth
  119. })
  120. this.setData({
  121. 'calendar.curYear': newYear,
  122. 'calendar.curMonth': newMonth
  123. })
  124. renderCalendar.call(this, newYear, newMonth)
  125. },
  126. /**
  127. * 日期点击事件
  128. * @param {!object} e 事件对象
  129. */
  130. tapDayItem(e) {
  131. const { idx, date = {} } = e.currentTarget.dataset
  132. const { day, disable } = date
  133. if (disable || !day) return
  134. const config = this.data.calendarConfig || this.config || {}
  135. const { multi, chooseAreaMode } = config
  136. if (multi) {
  137. whenMulitSelect.call(this, idx)
  138. } else if (chooseAreaMode) {
  139. whenChooseArea.call(this, idx)
  140. } else {
  141. whenSingleSelect.call(this, idx)
  142. }
  143. this.setData({
  144. 'calendar.noDefault': false
  145. })
  146. },
  147. doubleClickToToday() {
  148. if (this.config.multi || this.weekMode) return
  149. if (this.count === undefined) {
  150. this.count = 1
  151. } else {
  152. this.count += 1
  153. }
  154. if (this.lastClick) {
  155. const difference = new Date().getTime() - this.lastClick
  156. if (difference < 500 && this.count >= 2) {
  157. jump.call(this)
  158. }
  159. this.count = undefined
  160. this.lastClick = undefined
  161. } else {
  162. this.lastClick = new Date().getTime()
  163. }
  164. },
  165. /**
  166. * 日历滑动开始
  167. * @param {object} e
  168. */
  169. calendarTouchstart(e) {
  170. const t = e.touches[0]
  171. const startX = t.clientX
  172. const startY = t.clientY
  173. this.slideLock = true // 滑动事件加锁
  174. this.setData({
  175. 'gesture.startX': startX,
  176. 'gesture.startY': startY
  177. })
  178. },
  179. /**
  180. * 日历滑动中
  181. * @param {object} e
  182. */
  183. calendarTouchmove(e) {
  184. const { gesture } = this.data
  185. const { preventSwipe } = this.properties.calendarConfig
  186. if (!this.slideLock || preventSwipe) return
  187. if (slide.isLeft(gesture, e.touches[0])) {
  188. this.handleSwipe('left')
  189. this.slideLock = false
  190. }
  191. if (slide.isRight(gesture, e.touches[0])) {
  192. this.handleSwipe('right')
  193. this.slideLock = false
  194. }
  195. },
  196. calendarTouchend(e) {
  197. this.setData({
  198. 'calendar.leftSwipe': 0,
  199. 'calendar.rightSwipe': 0
  200. })
  201. },
  202. handleSwipe(direction) {
  203. let swipeKey = 'calendar.leftSwipe'
  204. let swipeCalendarType = 'next_month'
  205. let weekChangeType = 'next_week'
  206. if (direction === 'right') {
  207. swipeKey = 'calendar.rightSwipe'
  208. swipeCalendarType = 'prev_month'
  209. weekChangeType = 'prev_week'
  210. }
  211. this.setData({
  212. [swipeKey]: 1
  213. })
  214. this.currentYM = getCurrentYM()
  215. if (this.weekMode) {
  216. this.slideLock = false
  217. this.currentDates = getCalendarDates()
  218. if (weekChangeType === 'prev_week') {
  219. Week(this).calculatePrevWeekDays()
  220. } else if (weekChangeType === 'next_week') {
  221. Week(this).calculateNextWeekDays()
  222. }
  223. this.onSwipeCalendar(weekChangeType)
  224. this.onWeekChange(weekChangeType)
  225. return
  226. }
  227. this.chooseMonth(swipeCalendarType)
  228. this.onSwipeCalendar(swipeCalendarType)
  229. },
  230. onSwipeCalendar(direction) {
  231. this.triggerEvent('onSwipe', {
  232. directionType: direction,
  233. currentYM: this.currentYM
  234. })
  235. },
  236. onWeekChange(direction) {
  237. this.triggerEvent('whenChangeWeek', {
  238. current: {
  239. currentYM: this.currentYM,
  240. dates: [...this.currentDates]
  241. },
  242. next: {
  243. currentYM: getCurrentYM(),
  244. dates: getCalendarDates()
  245. },
  246. directionType: direction
  247. })
  248. this.currentDates = null
  249. this.currentYM = null
  250. }
  251. }
  252. })