rangeDate.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <template>
  2. <div style="display: flex;align-items: center;justify-content: space-between;">
  3. <div style="flex:1">
  4. <a-date-picker
  5. :size="size"
  6. :locale="locale"
  7. v-model="startValue"
  8. :allowClear="allowClear"
  9. :disabled-date="disabledStartDate"
  10. :show-time="showTime"
  11. :format="showTime?'YYYY-MM-DD hh:mm:ss':'YYYY-MM-DD'"
  12. placeholder="开始时间"
  13. :open="startOpen"
  14. inputReadOnly
  15. @openChange="handleStartOpenChange"
  16. @panelChange="handleStartPanelChange"
  17. :showToday="false"
  18. style="width:100%"
  19. >
  20. <div slot="renderExtraFooter" v-if="showShortcut">
  21. <a-button @click="setVal('date1')" type="link" size="small">今天</a-button>
  22. <a-button @click="setVal('date2')" type="link" size="small">近一个月</a-button>
  23. <a-button @click="setVal('date3')" type="link" size="small">本月</a-button>
  24. <a-button @click="setVal('date4')" type="link" size="small">上月</a-button>
  25. <a-button @click="setVal('date5')" v-if="showShortcut" type="link" size="small">近一年</a-button>
  26. <a-button @click="setVal('date6')" v-else type="link" size="small">近三个月</a-button>
  27. </div>
  28. </a-date-picker>
  29. </div>
  30. <span style="width: 20px;text-align: center;">至</span>
  31. <div style="flex:1">
  32. <a-date-picker
  33. :size="size"
  34. :locale="locale"
  35. v-model="endValue"
  36. :allowClear="allowClear"
  37. :disabled-date="disabledEndDate"
  38. :show-time="showTime"
  39. :format="showTime?'YYYY-MM-DD hh:mm:ss':'YYYY-MM-DD'"
  40. placeholder="结束时间"
  41. inputReadOnly
  42. :open="endOpen"
  43. @openChange="handleEndOpenChange"
  44. @panelChange="handleEndPanelChange"
  45. :showToday="false"
  46. style="width:100%"
  47. >
  48. <div slot="renderExtraFooter">
  49. <a-button @click="setVal('date1')" type="link" size="small">今天</a-button>
  50. <a-button @click="setVal('date2')" type="link" size="small">近一个月</a-button>
  51. <a-button @click="setVal('date3')" type="link" size="small">本月</a-button>
  52. <a-button @click="setVal('date4')" type="link" size="small">上月</a-button>
  53. <a-button @click="setVal('date5')" v-if="showShortcut" type="link" size="small">近一年</a-button>
  54. <a-button @click="setVal('date6')" v-else type="link" size="small">近三个月</a-button>
  55. </div>
  56. </a-date-picker>
  57. </div>
  58. </div>
  59. </template>
  60. <script>
  61. import locale from 'ant-design-vue/es/date-picker/locale/zh_CN';
  62. import moment from 'moment';//引入moment
  63. export default {
  64. props: {
  65. value: {
  66. type: Array,
  67. default: () => {
  68. return []
  69. }
  70. },
  71. size: {
  72. type: String,
  73. default: 'default'
  74. },
  75. showTime: {
  76. type: Boolean,
  77. default: false
  78. },
  79. allowClear: {
  80. type: Boolean,
  81. default: true
  82. },
  83. showShortcut: {
  84. type: Boolean,
  85. default: true
  86. },
  87. },
  88. data () {
  89. return {
  90. locale,
  91. startValue: null,
  92. endValue: null,
  93. endOpen: false,
  94. startOpen: false,
  95. ranges: {
  96. 'date1': [moment(), moment()],
  97. 'date2': [moment().subtract(1, 'months'), moment()],
  98. 'date3': [moment().startOf('month'), moment()],
  99. 'date4': [moment().subtract(1, 'months').startOf('month'), moment().subtract(1, 'months').endOf('month')],
  100. 'date5': [moment().subtract(1, 'years'), moment()],
  101. 'date6': [moment().subtract(3, 'months').startOf('month'), moment().subtract(3, 'months').endOf('month')]
  102. },
  103. startMode:'',
  104. endMode: ''
  105. }
  106. },
  107. watch: {
  108. startValue (val,old) {
  109. if(old&&!val){
  110. this.endValue = null
  111. }
  112. if(val && !this.endValue){
  113. this.endOpen = true
  114. }
  115. this.startValue = val || null
  116. this.changeInput()
  117. },
  118. endValue (val,old) {
  119. if(old&&!val){
  120. this.startValue = null
  121. }
  122. this.endValue = val || null
  123. this.changeInput()
  124. }
  125. },
  126. methods: {
  127. setVal (key) {
  128. this.startValue = this.ranges[key][0]
  129. this.endValue = this.ranges[key][1]
  130. this.startOpen = false
  131. this.endOpen = false
  132. },
  133. disabledStartDate (startValue) {
  134. const endValue = this.endValue
  135. const maxYearVs = moment().endOf('day') // 今天,包含今天
  136. if (endValue) {
  137. if (!this.startValue) {
  138. return startValue.valueOf() > moment(endValue, 'YYYY-MM-DD').add(1, 'days').valueOf() || startValue.valueOf() > maxYearVs.valueOf()
  139. }
  140. if(this.startMode == 'year'){
  141. return startValue.valueOf() > moment().endOf('year').valueOf()
  142. }
  143. if(this.startMode == 'month'){
  144. return startValue.valueOf() > moment().endOf('month').valueOf()
  145. }
  146. return startValue.valueOf() > moment(endValue).valueOf() || startValue.valueOf() > maxYearVs.valueOf()
  147. }
  148. return startValue.valueOf() > maxYearVs.valueOf()
  149. },
  150. disabledEndDate (endValue) {
  151. const startValue = this.startValue
  152. const maxYearVs = moment().endOf('day') // 今天,包含今天
  153. if (startValue) {
  154. if(this.endMode == 'year'){
  155. const sv = moment(startValue).startOf('year')
  156. return endValue.valueOf() < sv.valueOf() || endValue.valueOf() > moment().endOf('year').valueOf()
  157. }
  158. if(this.endMode == 'month'){
  159. const sv = moment(startValue).startOf('month')
  160. return endValue.valueOf() < sv.valueOf() || endValue.valueOf() > moment().endOf('month').valueOf()
  161. }
  162. return moment(startValue).valueOf() > endValue.valueOf() || endValue.valueOf() > maxYearVs.valueOf()
  163. }
  164. return endValue.valueOf() > maxYearVs.valueOf()
  165. },
  166. handleStartOpenChange (open) {
  167. if(!open && !this.endValue){
  168. this.endOpen = !!this.startValue
  169. }
  170. if(!open){
  171. this.startMode = ''
  172. }
  173. this.startOpen = open
  174. },
  175. handleEndOpenChange (open) {
  176. if(!open){
  177. this.endMode = ''
  178. }
  179. this.endOpen = open
  180. },
  181. handleStartPanelChange (v, mode) {
  182. console.log(v, mode)
  183. this.startMode = mode
  184. },
  185. handleEndPanelChange (v, mode) {
  186. console.log(v, mode)
  187. this.endMode = mode
  188. },
  189. changeInput () {
  190. const startValue = this.startValue
  191. const endValue = this.endValue
  192. console.log(startValue, endValue)
  193. let dateStrings = [startValue, endValue]
  194. if (!dateStrings[0] && !dateStrings[1]) {
  195. dateStrings = []
  196. } else {
  197. if (!this.showTime) {
  198. dateStrings[0] = dateStrings[0] ? moment(dateStrings[0]).format('YYYY-MM-DD 00:00:00') : ''
  199. dateStrings[1] = dateStrings[1] ? moment(dateStrings[1]).format('YYYY-MM-DD 23:59:59') : ''
  200. } else {
  201. dateStrings[0] = dateStrings[0] ? moment(dateStrings[0]).format('YYYY-MM-DD hh:mm:ss') : ''
  202. dateStrings[1] = dateStrings[1] ? moment(dateStrings[1]).format('YYYY-MM-DD hh:mm:ss') : ''
  203. }
  204. }
  205. this.$emit('change', dateStrings)
  206. },
  207. resetDate (val) {
  208. this.startValue = val && val[0] ? val[0] : null
  209. this.endValue = val && val[1] ? val[1] : null
  210. this.$emit('change', [])
  211. }
  212. }
  213. }
  214. </script>