index.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <template>
  2. <div class="cip-date-scope" :style="{width}">
  3. <basic-date-picker class="cip-date-range"
  4. :modelValue="modelValue"
  5. :config="config"
  6. @update:modelValue="val => emitDateInput(val)"
  7. ></basic-date-picker>
  8. <span class="cip-date-scope__link">至</span>
  9. <!-- 此处验证由上级处理-->
  10. <basic-date-picker :modelValue="otherValue"
  11. class="cip-date-range"
  12. :config="otherConfig"
  13. @update:modelValue="val => emitDateInput(val, 'otherValue')"
  14. ></basic-date-picker>
  15. </div>
  16. </template>
  17. <script>
  18. import BasicDatePicker from '../../basic/date-picker'
  19. import { computed } from 'vue'
  20. import { useFormInput } from '@cip/components/hooks/form-input'
  21. import { formInputProps } from '../../form-input-props'
  22. import dayjs from 'dayjs'
  23. import { isInputEmpty } from '@cip/utils/util'
  24. export default {
  25. components: { BasicDatePicker },
  26. props: formInputProps,
  27. emits: ['update:modelValue', 'update:otherValue'],
  28. setup (props, context) {
  29. const { emitModelValue, emitOtherValue, ...formInput } = useFormInput(props, context)
  30. const getNotEmptyValue = (a, b) => {
  31. if (!isInputEmpty(a) && !isInputEmpty(b)) return [a, b]
  32. if (!isInputEmpty(a)) return [a]
  33. if (!isInputEmpty(b)) return [b]
  34. return []
  35. }
  36. // 用于比较大小
  37. const dateInfoToTimes = (dateInfoList) => {
  38. return dateInfoList.map(v => {
  39. if (typeof v === 'number') return v
  40. if (v instanceof Date) return v.getTime()
  41. return dayjs(v).valueOf()
  42. })
  43. }
  44. const config = computed(() => {
  45. const config = { ...props.config }
  46. // config.min = config.min 默认
  47. config.max = Math.min(...dateInfoToTimes(getNotEmptyValue(props.otherValue, props.config.max)))
  48. return config
  49. })
  50. const otherConfig = computed(() => {
  51. const config = { ...props.config }
  52. config.min = Math.max(...dateInfoToTimes(getNotEmptyValue(props.modelValue, props.config.otherMin ?? props.config.min)))
  53. if (!isInputEmpty(props.config.otherMax)) config.max = props.config.otherMax
  54. config.placeholder = props.config.otherPlaceholder
  55. return config
  56. })
  57. const formatter = computed(() => {
  58. return props.config?.formatter ?? (type.value === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD')
  59. })
  60. // range使用date和datetime两种类型
  61. const type = computed(() => {
  62. const viewType = props.config?.viewType ?? 'date'
  63. return ['date', 'datetime'].includes(viewType) ? viewType : 'date'
  64. })
  65. /**
  66. * element plus的date-picker组件不再提供value-format属性
  67. * 提交val时候引入dayjs的format方法手动转换
  68. *
  69. * 时间戳时会报modelValue不能接收number
  70. */
  71. const emitDateInput = (val, withOther) => {
  72. let value = ''
  73. if (!val) {
  74. value = ''
  75. } else if (props.config?.isTimestamp) {
  76. value = new Date(val).getTime()
  77. } else {
  78. value = dayjs(val).format(formatter.value)
  79. }
  80. if (withOther) {
  81. emitOtherValue(value)
  82. } else {
  83. emitModelValue(value)
  84. }
  85. }
  86. return {
  87. ...formInput,
  88. emitDateInput,
  89. config,
  90. otherConfig
  91. }
  92. }
  93. }
  94. </script>
  95. <style lang="less">
  96. .cip-date-scope{
  97. display: flex;
  98. flex-grow: 1;
  99. width: 100%;
  100. align-content: center;
  101. .cip-date-range{
  102. flex-grow: 1;
  103. flex-basis: 0;
  104. display: flex;
  105. }
  106. &__link{
  107. // is-success 将导致字体变色
  108. color: #999;
  109. margin: 0 8px;
  110. }
  111. .el-date-editor.el-input{
  112. width: 100%;
  113. flex-shrink: 1;
  114. }
  115. // clear图标在range时比较占用空间
  116. .el-input--suffix .el-input__inner{
  117. padding-right: 22px;
  118. }
  119. .el-input__suffix{
  120. right: 0;
  121. }
  122. }
  123. </style>