index.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import { Button, Calendar, Dialog, Icon, Image, Popup, showToast, Tag, Toast } from 'vant'
  2. import { defineComponent } from 'vue'
  3. import dayjs from 'dayjs'
  4. import styles from './index.module.less'
  5. import IconArrow from '../../images/icon_arrow.png'
  6. import IconArrowDefault from '../../images/icon_arrow_default.png'
  7. import isToday from 'dayjs/plugin/isToday'
  8. import OHeader from '@/components/o-header'
  9. dayjs.extend(isToday)
  10. export default defineComponent({
  11. name: 'calendar',
  12. props: {
  13. calendarDate: {
  14. type: String,
  15. default: ''
  16. },
  17. // 接口数据
  18. list: {
  19. type: Array,
  20. default: () => []
  21. },
  22. /**
  23. * 点击并选中任意日期时触发
  24. */
  25. onSelect: {
  26. type: Function,
  27. default: (date: Date) => {}
  28. },
  29. /**
  30. * 上一月,不能小于当月
  31. */
  32. prevMonth: {
  33. type: Function,
  34. default: (date: Date) => {}
  35. },
  36. /**
  37. * 下一月,暂无限制
  38. */
  39. nextMonth: {
  40. type: Function,
  41. default: (date: Date) => {}
  42. },
  43. /**
  44. * 日期选择结束时触发
  45. */
  46. selectDay: {
  47. type: Function,
  48. default: (obj: any) => {}
  49. }
  50. },
  51. data() {
  52. return {
  53. minDate: new Date(),
  54. maxDate: new Date(),
  55. currentDate: dayjs().add(1, 'day').toDate(), // 当前日历日期
  56. subtitle: '',
  57. dayList: [],
  58. selectDays: [] as any
  59. }
  60. },
  61. computed: {
  62. arrowStatus() {
  63. // 上月箭头状态
  64. return !dayjs().add(1, 'day').isBefore(dayjs(this.currentDate), 'month')
  65. },
  66. selectDayTitle() {
  67. // 选中日期标题
  68. return dayjs(this.currentDate).format('YYYY-MM-DD')
  69. },
  70. isPrevDay() {
  71. // 是否可以点击上一天
  72. return dayjs(this.currentDate).subtract(1, 'day').isBefore(dayjs(this.minDate), 'day')
  73. },
  74. isNextDay() {
  75. // 是否可以点击下一天
  76. return dayjs(this.currentDate).add(1, 'day').isAfter(dayjs(this.maxDate), 'day')
  77. }
  78. },
  79. mounted() {
  80. // 初始化标题和最大显示日期
  81. this.subtitle = dayjs().add(1, 'day').format('YYYY年MM月')
  82. this.maxDate = dayjs().add(1, 'day').endOf('month').toDate()
  83. this.minDate = dayjs().add(1, 'day').toDate()
  84. console.log(this.list, 'this.list')
  85. },
  86. methods: {
  87. formatter(date: any) {
  88. const dateStr = dayjs(date.date).format('YYYY-MM-DD')
  89. let isActive = false // 是否可选
  90. this.list.forEach((item: any) => {
  91. if (item.calendarDate === dateStr) {
  92. isActive = true
  93. }
  94. })
  95. // 判断是否有课程 并且 时间在当前时间之后
  96. if (isActive && dayjs().isBefore(dayjs(date.date))) {
  97. date.bottomInfo = '可选'
  98. if (dayjs(dateStr).isSame(this.calendarDate)) {
  99. date.type = 'selected'
  100. } else {
  101. date.type = ''
  102. }
  103. } else {
  104. date.type = 'disabled'
  105. }
  106. return date
  107. },
  108. onPrevMonth() {
  109. // 上一月
  110. if (this.arrowStatus) return
  111. const tempDate = dayjs(this.currentDate).subtract(1, 'month')
  112. this._monthChange(tempDate)
  113. this.prevMonth && this.prevMonth(this.minDate)
  114. },
  115. onNextMonth() {
  116. // 下一月
  117. const tempDate = dayjs(this.currentDate).add(1, 'month')
  118. this._monthChange(tempDate)
  119. this.nextMonth && this.nextMonth(this.minDate)
  120. },
  121. _monthChange(date: any) {
  122. // 月份改变
  123. // 需要判断是否是当月,需要单独处理最小时间
  124. const currentMinDate = dayjs().add(1, 'day').toDate()
  125. const monthMinDate = date.startOf('month').toDate()
  126. this.minDate = dayjs(currentMinDate).isAfter(monthMinDate) ? currentMinDate : monthMinDate
  127. this.maxDate = date.endOf('month').toDate()
  128. this.currentDate = date.toDate()
  129. this.$emit('update:calendarDate', date.toDate())
  130. this.subtitle = date.format('YYYY年MM月')
  131. },
  132. onPrevDay() {
  133. // 获取上一天的数据
  134. const tempDate = dayjs(this.currentDate).subtract(1, 'day')
  135. this._dayChange(tempDate.toDate())
  136. },
  137. onNextDay() {
  138. // 获取下一天的数据
  139. const tempDate = dayjs(this.currentDate).add(1, 'day')
  140. this._dayChange(tempDate.toDate())
  141. },
  142. onDateSelect(date: any) {
  143. // 选择日历上某一个日期
  144. this._dayChange(date)
  145. this.onSelect && this.onSelect(date)
  146. },
  147. _dayChange(date: Date) {
  148. this.currentDate = date // 更新当前日期
  149. this.$emit('update:calendarDate', dayjs(date).format('YYYY-MM-DD'))
  150. }
  151. },
  152. render() {
  153. return (
  154. <div class={styles.calendarContainer}>
  155. <OHeader title="训练日期" border={false} background="transparent" />
  156. <Calendar
  157. class={styles.calendar}
  158. showTitle={false}
  159. poppable={false}
  160. showConfirm={false}
  161. showMark={false}
  162. firstDayOfWeek={1}
  163. rowHeight={62}
  164. minDate={this.minDate}
  165. maxDate={this.maxDate}
  166. color="var(--van-primary)"
  167. formatter={this.formatter}
  168. onSelect={this.onDateSelect}
  169. v-slots={{
  170. subtitle: () => (
  171. <div class={styles.subtitle}>
  172. <span>{this.subtitle}</span>
  173. <div>
  174. <Icon
  175. name={this.arrowStatus ? IconArrowDefault : IconArrow}
  176. size={22}
  177. class={[styles.right]}
  178. onClick={this.onPrevMonth}
  179. />
  180. <Icon name={IconArrow} size={22} onClick={this.onNextMonth} />
  181. </div>
  182. </div>
  183. )
  184. }}
  185. />
  186. </div>
  187. )
  188. }
  189. })