index.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. import plugins from './plugins/index'
  2. import { calcJumpData } from './core'
  3. import { renderCalendar } from './render'
  4. import { calcTargetYMInfo } from './helper'
  5. import { dateUtil, calendarGesture, logger } from './utils/index'
  6. Component({
  7. options: {
  8. styleIsolation: 'apply-shared',
  9. multipleSlots: true // 在组件定义时的选项中启用多slot支持
  10. },
  11. properties: {
  12. config: {
  13. type: Object,
  14. value: {}
  15. }
  16. },
  17. lifetimes: {
  18. attached: function() {
  19. this.initComp()
  20. }
  21. },
  22. methods: {
  23. initComp() {
  24. const calendarConfig = this.setDefaultDisableDate()
  25. this.setConfig(calendarConfig)
  26. },
  27. // 禁用某天日期配置默认为今天
  28. setDefaultDisableDate() {
  29. const calendarConfig = this.properties.config || {}
  30. if (calendarConfig.disableMode && !calendarConfig.disableMode.date) {
  31. calendarConfig.disableMode.date = dateUtil.toTimeStr(
  32. dateUtil.todayFMD()
  33. )
  34. }
  35. return calendarConfig
  36. },
  37. initCalendar(config) {
  38. const { defaultDate } = config
  39. let date = dateUtil.todayFMD()
  40. if (defaultDate && typeof defaultDate === 'string') {
  41. const dateInfo = defaultDate.split('-')
  42. if (dateInfo.length < 3) {
  43. return logger.warn('defaultDate配置格式应为: 2018-4-2 或 2018-04-02')
  44. } else {
  45. date = {
  46. year: +dateInfo[0],
  47. month: +dateInfo[1],
  48. date: +dateInfo[2]
  49. }
  50. }
  51. }
  52. const waitRenderData = calcJumpData({
  53. dateInfo: date,
  54. config
  55. })
  56. const timestamp = dateUtil.todayTimestamp()
  57. if (config.autoChoosedWhenJump) {
  58. const target = waitRenderData.dates.filter(
  59. item => dateUtil.toTimeStr(item) === dateUtil.toTimeStr(date)
  60. )
  61. if (target && target.length) {
  62. if (!waitRenderData.selectedDates) {
  63. waitRenderData.selectedDates = target
  64. } else {
  65. waitRenderData.selectedDates.push(target[0])
  66. }
  67. }
  68. }
  69. return {
  70. ...waitRenderData,
  71. todayTimestamp: timestamp,
  72. weeksCh: dateUtil.getWeekHeader(config.firstDayOfWeek)
  73. }
  74. },
  75. setConfig(config) {
  76. if (config.markToday && typeof config.markToday === 'string') {
  77. config.highlightToday = true
  78. }
  79. config.theme = config.theme || 'default'
  80. this.setData(
  81. {
  82. config
  83. },
  84. () => {
  85. for (let plugin of plugins.installed) {
  86. const [, p] = plugin
  87. if (typeof p.install === 'function') {
  88. p.install(this)
  89. }
  90. if (typeof p.methods === 'function') {
  91. const methods = p.methods(this)
  92. for (let fnName in methods) {
  93. if (fnName.startsWith('__')) continue
  94. const fn = methods[fnName]
  95. if (typeof fn === 'function') {
  96. if (!this.calendar) this.calendar = {}
  97. this.calendar[fnName] = fn
  98. }
  99. }
  100. }
  101. }
  102. const initData = this.initCalendar(config)
  103. renderCalendar.call(this, initData, config)
  104. }
  105. )
  106. },
  107. tapDate(e) {
  108. const { info } = e.currentTarget.dataset
  109. const { date, disable } = info || {}
  110. if (disable || !date) return
  111. const { calendar, config } = this.data
  112. let calendarData = calendar
  113. let calendarConfig = config
  114. if (config.takeoverTap) {
  115. return this.triggerEvent('takeoverTap', info)
  116. }
  117. for (let plugin of plugins.installed) {
  118. const [, p] = plugin
  119. if (typeof p.onTapDate === 'function') {
  120. const {
  121. calendarData: __calendarData,
  122. calendarConfig: __calendarConfig
  123. } = p.onTapDate(info, calendarData, calendarConfig)
  124. calendarData = __calendarData
  125. calendarConfig = __calendarConfig
  126. }
  127. }
  128. renderCalendar.call(this, calendarData, calendarConfig).then(() => {
  129. this.triggerEvent('afterTapDate', info)
  130. })
  131. },
  132. /**
  133. * 日历滑动开始
  134. * @param {object} e
  135. */
  136. calendarTouchstart(e) {
  137. const t = e.touches[0]
  138. const startX = t.clientX
  139. const startY = t.clientY
  140. this.swipeLock = true
  141. this.setData({
  142. 'gesture.startX': startX,
  143. 'gesture.startY': startY
  144. })
  145. },
  146. /**
  147. * 日历滑动中
  148. * @param {object} e
  149. */
  150. calendarTouchmove(e) {
  151. const { gesture } = this.data
  152. const { preventSwipe } = this.properties.config
  153. if (!this.swipeLock || preventSwipe) return
  154. if (calendarGesture.isLeft(gesture, e.touches[0])) {
  155. this.handleSwipe('left')
  156. this.swipeLock = false
  157. }
  158. if (calendarGesture.isRight(gesture, e.touches[0])) {
  159. this.handleSwipe('right')
  160. this.swipeLock = false
  161. }
  162. },
  163. calendarTouchend(e) {
  164. this.setData({
  165. 'calendar.leftSwipe': 0,
  166. 'calendar.rightSwipe': 0
  167. })
  168. },
  169. handleSwipe(direction) {
  170. let swipeKey = 'calendar.leftSwipe'
  171. if (direction === 'right') {
  172. swipeKey = 'calendar.rightSwipe'
  173. }
  174. this.setData({
  175. [swipeKey]: 1
  176. })
  177. const { calendar } = this.data
  178. let calendarData = calendar
  179. const { curYear, curMonth } = calendarData
  180. const getMonthInfo = calcTargetYMInfo()[direction]
  181. const target = getMonthInfo({
  182. year: +curYear,
  183. month: +curMonth
  184. })
  185. target.direction = direction
  186. this.renderCalendar(target)
  187. },
  188. changeDate(e) {
  189. const { type } = e.currentTarget.dataset
  190. const { calendar: calendarData } = this.data
  191. const { curYear, curMonth } = calendarData
  192. const getMonthInfo = calcTargetYMInfo()[type]
  193. const target = getMonthInfo({
  194. year: +curYear,
  195. month: +curMonth
  196. })
  197. target.direction = type
  198. this.renderCalendar(target)
  199. },
  200. renderCalendar(target) {
  201. let { calendar: calendarData, config } = this.data
  202. const { curYear, curMonth } = calendarData || {}
  203. for (let plugin of plugins.installed) {
  204. const [, p] = plugin
  205. if (typeof p.onSwitchCalendar === 'function') {
  206. calendarData = p.onSwitchCalendar(target, calendarData, this)
  207. }
  208. }
  209. return renderCalendar.call(this, calendarData, config).then(() => {
  210. let triggerEventName = 'whenChangeMonth'
  211. if (config.weekMode) {
  212. triggerEventName = 'whenChangeWeek'
  213. }
  214. this.triggerEvent(triggerEventName, {
  215. current: {
  216. year: +curYear,
  217. month: +curMonth
  218. },
  219. next: target
  220. })
  221. this.triggerEvent('onSwipe', {
  222. current: {
  223. year: +curYear,
  224. month: +curMonth
  225. },
  226. next: target,
  227. type: triggerEventName
  228. })
  229. })
  230. },
  231. gotoSearch(){
  232. wx.navigateTo({
  233. url: '/pages/search/index',
  234. })
  235. },
  236. doubleClickJumpToToday() {
  237. const { multi, weekMode } = this.calendar.getCalendarConfig() || {}
  238. if (multi || weekMode) return
  239. if (this.count === undefined) {
  240. this.count = 1
  241. } else {
  242. this.count += 1
  243. }
  244. if (this.lastClick) {
  245. const difference = new Date().getTime() - this.lastClick
  246. if (
  247. difference < 500 &&
  248. this.count >= 2 &&
  249. typeof this.calendar.jump === 'function'
  250. ) {
  251. const today = dateUtil.todayFMD()
  252. this.calendar.jump(today)
  253. }
  254. this.count = undefined
  255. this.lastClick = undefined
  256. } else {
  257. this.lastClick = new Date().getTime()
  258. }
  259. }
  260. }
  261. })