index.js 4.0 KB

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