dateTimeRange.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <template>
  2. <div class="dateTimeRangeBox">
  3. <van-field
  4. :label="label"
  5. :placeholder="placeholder"
  6. v-model="currentDateTime"
  7. readonly
  8. @touchstart="clickHandler"
  9. />
  10. <van-popup class="detail-popup" v-model:show="popupShow" position="bottom">
  11. <van-picker
  12. v-model="selectDateTime"
  13. title="时间选择"
  14. :columns="dateTimeRangeColumns"
  15. @change="changeHandle"
  16. @confirm="confirmHandle"
  17. @cancel="cancelHandle"
  18. />
  19. </van-popup>
  20. </div>
  21. </template>
  22. <script lang="ts" setup>
  23. defineOptions({
  24. name: 'DateTimeRange'
  25. })
  26. const props = defineProps<{
  27. label: string
  28. placeholder: string
  29. modelValue: string
  30. }>()
  31. const emit = defineEmits<{
  32. (e: 'update:modelValue', payload: any): void
  33. (e: 'change', payload: string):void
  34. }>()
  35. const currentYear: number = new Date().getFullYear();
  36. const currentMonth: number = new Date().getMonth()+1;
  37. const currentDay: number = new Date().getDate();
  38. const selectYear = ref<string>(currentYear.toString());
  39. const selectMonth = ref<string>(currentMonth.toString());
  40. const currentDateTime = ref<string>('')
  41. const selectDateTime = ref<string[]>([])
  42. const defaultDateTime: string[] = [currentYear.toString(), fillZero(currentMonth), fillZero(currentDay), '00', '00']
  43. if (props.modelValue) {
  44. selectDateTime.value = formatDateTimeArr(props.modelValue);
  45. currentDateTime.value = props.modelValue
  46. } else {
  47. selectDateTime.value = defaultDateTime
  48. }
  49. watch(() => props.modelValue, (newVal) => {
  50. if(!newVal){
  51. currentDateTime.value = ''
  52. selectDateTime.value = defaultDateTime
  53. return;
  54. }
  55. currentDateTime.value = newVal
  56. const newArr = formatDateTimeArr(newVal);
  57. selectDateTime.value = newArr
  58. selectYear.value = newArr[0].toString()
  59. selectMonth.value = newArr[1].toString()
  60. setMonthByDay(newArr[0],newArr[1]);
  61. })
  62. /***
  63. * 固定统计年、月、时、分数据
  64. */
  65. const yearList: string[] = []
  66. const monthList: string[] = []
  67. for (let i = 2012; i < currentYear + 5; i++){
  68. yearList.push(i.toString())
  69. }
  70. for (let i = 1; i <= 12; i++){
  71. monthList.push(fillZero(i));
  72. }
  73. const houseList = [];
  74. for (let i = 0; i <= 23; i++){
  75. houseList.push(fillZero(i));
  76. }
  77. const minuteList = ['00', '30']
  78. const dateTimeRangeColumns = reactive([
  79. yearList.map(val => {
  80. return {text: val, value: val}
  81. }),
  82. monthList.map(val => {
  83. return {text: val, value: val}
  84. }),
  85. [],
  86. houseList.map(val => {
  87. return {text: val, value: val}
  88. }),
  89. minuteList.map(val => {
  90. return {text: val, value: val}
  91. }),
  92. ]);
  93. /***
  94. * 日单独处理,每个月日期不一样
  95. */
  96. function getDaysInMonth(year: number|string, month: number|string) {
  97. return new Date(year as number, month as number, 0).getDate();
  98. }
  99. function setMonthByDay(year: number|string, month: number|string) {
  100. const day = getDaysInMonth(year, month);
  101. const dayList: any[] = [];
  102. for (let i = 1; i <= day; i++){
  103. const val = fillZero(i);
  104. dayList.push({text: val, value: val});
  105. }
  106. dateTimeRangeColumns[2] = dayList;
  107. }
  108. function fillZero(num: number): string {
  109. const num2 = Number(num);
  110. return num < 10 ? "0" + num2.toString() : num2.toString()
  111. }
  112. /***
  113. * 格式化YYYY-MM-DD HH:MM:SS转成[yyy, mm, dd, hh, mm, dd]
  114. */
  115. function formatDateTimeArr(dateTime: string): string[] {
  116. if (!dateTime){
  117. console.warn('formatDateTimeArr方法参数dateTime值不能为空!')
  118. return []
  119. }
  120. const dateTimeArr = dateTime.split(' ');
  121. if (dateTimeArr.length < 2) {
  122. throw new Error('dateTime格式不正确! 请符合:YYYY-MM-DD HH:MM:SS');
  123. }
  124. const dateArr: string[] = dateTimeArr[0].split('-');
  125. const timeArr: string[] = dateTimeArr[1].split(':');
  126. return dateArr.concat(timeArr) as string[];
  127. }
  128. /**
  129. * 格式化[yyy, mm, dd, hh, mm, dd]转成 YYYY-MM-DD HH:MM:SS
  130. **/
  131. function formatDateTimeByArr(arr: string[]): string {
  132. if (!arr || arr.length === 0) {
  133. console.warn('formatDateTimeByArr方法参数arr值不能为空!')
  134. return ''
  135. }
  136. const dateArr: string[] = []
  137. arr[0] ? dateArr.push(arr[0]) : null
  138. arr[1] ? dateArr.push(arr[1]) : null
  139. arr[2] ? dateArr.push(arr[2]) : null
  140. const timeArr: string[] = []
  141. arr[3] ? timeArr.push(arr[3]) : null
  142. arr[4] ? timeArr.push(arr[4]) : null
  143. arr[5] ? timeArr.push(arr[5]) : null
  144. return dateArr.join('-') +' ' + timeArr.join(':')
  145. }
  146. setMonthByDay(currentYear, currentMonth);
  147. const changeHandle = (val: any) => {
  148. const arr = val.selectedValues;
  149. if (selectYear.value !== arr[0] || selectMonth.value !== arr[1]) {
  150. setMonthByDay(arr[0], arr[1]);
  151. selectYear.value = arr[0];
  152. selectMonth.value = arr[1];
  153. const dateTimeStr:string = formatDateTimeByArr(arr);
  154. currentDateTime.value = dateTimeStr
  155. emit('update:modelValue', dateTimeStr)
  156. }
  157. }
  158. const confirmHandle = () => {
  159. const dateTimeStr:string = formatDateTimeByArr(selectDateTime.value);
  160. currentDateTime.value = dateTimeStr
  161. emit('update:modelValue', dateTimeStr)
  162. emit('change', dateTimeStr)
  163. popupShow.value = false;
  164. }
  165. const cancelHandle = () => {
  166. popupShow.value = false;
  167. }
  168. const popupShow = ref<boolean>(false)
  169. const clickHandler = () => {
  170. const time = setTimeout(() => {
  171. popupShow.value = !popupShow.value
  172. clearTimeout(time)
  173. }, 200)
  174. }
  175. </script>
  176. <style lang="scope" scoped>
  177. </style>