index.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import { VantComponent } from '../../../common/component';
  2. import { getMonthEndDay, compareDay, getPrevDay, getNextDay, } from '../../utils';
  3. VantComponent({
  4. props: {
  5. date: {
  6. type: null,
  7. observer: 'setDays',
  8. },
  9. type: {
  10. type: String,
  11. observer: 'setDays',
  12. },
  13. color: String,
  14. minDate: {
  15. type: null,
  16. observer: 'setDays',
  17. },
  18. maxDate: {
  19. type: null,
  20. observer: 'setDays',
  21. },
  22. showMark: Boolean,
  23. rowHeight: null,
  24. formatter: {
  25. type: null,
  26. observer: 'setDays',
  27. },
  28. currentDate: {
  29. type: null,
  30. observer: 'setDays',
  31. },
  32. firstDayOfWeek: {
  33. type: Number,
  34. observer: 'setDays',
  35. },
  36. allowSameDay: Boolean,
  37. showSubtitle: Boolean,
  38. showMonthTitle: Boolean,
  39. },
  40. data: {
  41. visible: true,
  42. days: [],
  43. },
  44. methods: {
  45. onClick(event) {
  46. const { index } = event.currentTarget.dataset;
  47. const item = this.data.days[index];
  48. if (item.type !== 'disabled') {
  49. this.$emit('click', item);
  50. }
  51. },
  52. setDays() {
  53. const days = [];
  54. const startDate = new Date(this.data.date);
  55. const year = startDate.getFullYear();
  56. const month = startDate.getMonth();
  57. const totalDay = getMonthEndDay(startDate.getFullYear(), startDate.getMonth() + 1);
  58. for (let day = 1; day <= totalDay; day++) {
  59. const date = new Date(year, month, day);
  60. const type = this.getDayType(date);
  61. let config = {
  62. date,
  63. type,
  64. text: day,
  65. bottomInfo: this.getBottomInfo(type),
  66. };
  67. if (this.data.formatter) {
  68. config = this.data.formatter(config);
  69. }
  70. days.push(config);
  71. }
  72. this.setData({ days });
  73. },
  74. getMultipleDayType(day) {
  75. const { currentDate } = this.data;
  76. if (!Array.isArray(currentDate)) {
  77. return '';
  78. }
  79. const isSelected = (date) => currentDate.some((item) => compareDay(item, date) === 0);
  80. if (isSelected(day)) {
  81. const prevDay = getPrevDay(day);
  82. const nextDay = getNextDay(day);
  83. const prevSelected = isSelected(prevDay);
  84. const nextSelected = isSelected(nextDay);
  85. if (prevSelected && nextSelected) {
  86. return 'multiple-middle';
  87. }
  88. if (prevSelected) {
  89. return 'end';
  90. }
  91. return nextSelected ? 'start' : 'multiple-selected';
  92. }
  93. return '';
  94. },
  95. getRangeDayType(day) {
  96. const { currentDate, allowSameDay } = this.data;
  97. if (!Array.isArray(currentDate)) {
  98. return '';
  99. }
  100. const [startDay, endDay] = currentDate;
  101. if (!startDay) {
  102. return '';
  103. }
  104. const compareToStart = compareDay(day, startDay);
  105. if (!endDay) {
  106. return compareToStart === 0 ? 'start' : '';
  107. }
  108. const compareToEnd = compareDay(day, endDay);
  109. if (compareToStart === 0 && compareToEnd === 0 && allowSameDay) {
  110. return 'start-end';
  111. }
  112. if (compareToStart === 0) {
  113. return 'start';
  114. }
  115. if (compareToEnd === 0) {
  116. return 'end';
  117. }
  118. if (compareToStart > 0 && compareToEnd < 0) {
  119. return 'middle';
  120. }
  121. return '';
  122. },
  123. getDayType(day) {
  124. const { type, minDate, maxDate, currentDate } = this.data;
  125. if (compareDay(day, minDate) < 0 || compareDay(day, maxDate) > 0) {
  126. return 'disabled';
  127. }
  128. if (type === 'single') {
  129. return compareDay(day, currentDate) === 0 ? 'selected' : '';
  130. }
  131. if (type === 'multiple') {
  132. return this.getMultipleDayType(day);
  133. }
  134. /* istanbul ignore else */
  135. if (type === 'range') {
  136. return this.getRangeDayType(day);
  137. }
  138. return '';
  139. },
  140. getBottomInfo(type) {
  141. if (this.data.type === 'range') {
  142. if (type === 'start') {
  143. return '开始';
  144. }
  145. if (type === 'end') {
  146. return '结束';
  147. }
  148. if (type === 'start-end') {
  149. return '开始/结束';
  150. }
  151. }
  152. },
  153. },
  154. });