date-picker.uvue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <template>
  2. <view class="date-picker">
  3. <view class="date-item" :class="{'no-margin': !showLabel}">
  4. <text class="date-label" v-if="showLabel && label.length > 0" :style="{ width: labelWidth }">{{ label }}</text>
  5. <view class="date-input-box" @click="showPicker = true">
  6. <text class="date-input-text" :class="{'placeholder': modelValue.length == 0}">{{ displayText }}</text>
  7. <view class="date-input-icons">
  8. <image v-if="clearable && modelValue.length > 0" class="date-input-clear" src="/static/images/common/2.png" mode="aspectFit" @click.stop="handleClear"></image>
  9. <image class="date-input-arrow" src="/static/images/common/1.png" mode="aspectFit"></image>
  10. </view>
  11. </view>
  12. </view>
  13. <!-- 日期选择器弹窗 -->
  14. <l-popup v-model="showPicker" position="bottom">
  15. <l-date-time-picker
  16. v-model="innerValue"
  17. :title="title"
  18. title-style="font-size: 32rpx; font-weight: 500; color: #000000;"
  19. cancel-style="font-size: 32rpx; color: #888888;"
  20. confirm-style="font-size: 32rpx; color: #1890ff;"
  21. mode="年月日"
  22. format="YYYY-MM-DD"
  23. cancel-btn="取消"
  24. confirm-btn="确定"
  25. :start="start"
  26. :end="end"
  27. @cancel="showPicker = false"
  28. @confirm="handleConfirm"
  29. >
  30. </l-date-time-picker>
  31. </l-popup>
  32. </view>
  33. </template>
  34. <script setup lang="uts">
  35. import { ref, computed } from 'vue'
  36. // Props 定义
  37. type Props = {
  38. modelValue: string
  39. label?: string
  40. placeholder?: string
  41. title?: string
  42. start?: string
  43. end?: string
  44. labelWidth?: string
  45. showLabel?: boolean
  46. clearable?: boolean
  47. }
  48. const props = withDefaults(defineProps<Props>(), {
  49. label: '',
  50. placeholder: '请选择日期',
  51. title: '选择日期',
  52. start: '',
  53. end: '',
  54. labelWidth: '140rpx',
  55. showLabel: true,
  56. clearable: true
  57. })
  58. // Emits 定义
  59. const emit = defineEmits<{
  60. (e: 'update:modelValue', value: string): void
  61. }>()
  62. // 弹窗显示状态
  63. const showPicker = ref<boolean>(false)
  64. // 内部值
  65. const innerValue = ref<string>(props.modelValue)
  66. // 显示文本
  67. const displayText = computed<string>(() => {
  68. return props.modelValue.length > 0 ? props.modelValue : props.placeholder
  69. })
  70. // 确认选择
  71. const handleConfirm = (value: string): void => {
  72. emit('update:modelValue', value)
  73. showPicker.value = false
  74. }
  75. // 清除选择
  76. const handleClear = (): void => {
  77. emit('update:modelValue', '')
  78. innerValue.value = ''
  79. }
  80. </script>
  81. <style lang="scss">
  82. .date-picker {
  83. .date-item {
  84. display: flex;
  85. flex-direction: row;
  86. align-items: center;
  87. margin-bottom: 24rpx;
  88. &.no-margin {
  89. margin-bottom: 0;
  90. }
  91. .date-label {
  92. display: flex;
  93. align-items: center;
  94. justify-content: flex-start;
  95. font-weight: 400;
  96. font-size: 28rpx;
  97. color: #6e7580;
  98. }
  99. .date-input-box {
  100. flex: 1;
  101. display: flex;
  102. flex-direction: row;
  103. align-items: center;
  104. justify-content: space-between;
  105. padding: 20rpx;
  106. background-color: #f5f7fa;
  107. border-radius: 8rpx;
  108. .date-input-text {
  109. font-weight: 400;
  110. font-size: 28rpx;
  111. color: #131415;
  112. flex: 1;
  113. &.placeholder {
  114. color: #999999;
  115. }
  116. }
  117. .date-input-icons {
  118. display: flex;
  119. flex-direction: row;
  120. align-items: center;
  121. margin-left: 20rpx;
  122. .date-input-clear {
  123. width: 28rpx;
  124. height: 28rpx;
  125. margin-right: 12rpx;
  126. }
  127. .date-input-arrow {
  128. width: 24rpx;
  129. height: 24rpx;
  130. }
  131. }
  132. }
  133. }
  134. }
  135. </style>