| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- <template>
- <view class="date-range-picker">
- <view class="date-range-item" :class="{'no-margin': !showLabel}">
- <text class="date-range-label" v-if="showLabel && label.length > 0" :style="{ width: labelWidth }">{{ label }}</text>
- <view class="date-range-input-box" @click="showStartPicker = true">
- <text class="date-range-input-text" :class="{'placeholder': props.startValue.length == 0 || props.endValue.length == 0}">{{ displayText }}</text>
- <view class="date-range-input-icons">
- <image v-if="clearable && props.startValue.length > 0 && props.endValue.length > 0" class="date-range-input-clear" src="/static/images/common/2.png" mode="aspectFit" @click.stop="handleClear"></image>
- <image class="date-range-input-arrow" src="/static/images/common/1.png" mode="aspectFit"></image>
- </view>
- </view>
- </view>
- <!-- 开始日期选择器 -->
- <l-popup v-model="showStartPicker" position="bottom">
- <l-date-time-picker
- v-model="innerStartValue"
- :title="startTitle"
- title-style="font-size: 32rpx; font-weight: 500; color: #000000;"
- cancel-style="font-size: 32rpx; color: #888888;"
- confirm-style="font-size: 32rpx; color: #1890ff;"
- mode="年月日"
- format="YYYY-MM-DD"
- cancel-btn="取消"
- confirm-btn="确定"
- :start="start"
- :end="end"
- @cancel="showStartPicker = false"
- @confirm="handleStartConfirm"
- >
- </l-date-time-picker>
- </l-popup>
- <!-- 结束日期选择器 -->
- <l-popup v-model="showEndPicker" position="bottom">
- <l-date-time-picker
- v-model="innerEndValue"
- :title="endTitle"
- title-style="font-size: 32rpx; font-weight: 500; color: #000000;"
- cancel-style="font-size: 32rpx; color: #888888;"
- confirm-style="font-size: 32rpx; color: #1890ff;"
- mode="年月日"
- format="YYYY-MM-DD"
- cancel-btn="取消"
- confirm-btn="确定"
- :start="start"
- :end="end"
- @cancel="showEndPicker = false"
- @confirm="handleEndConfirm"
- >
- </l-date-time-picker>
- </l-popup>
- </view>
- </template>
- <script setup lang="uts">
- import { ref, computed } from 'vue'
- // Props 定义
- type Props = {
- startValue: string
- endValue: string
- label?: string
- placeholder?: string
- startTitle?: string
- endTitle?: string
- start?: string
- end?: string
- labelWidth?: string
- showLabel?: boolean
- clearable?: boolean
- }
- const props = withDefaults(defineProps<Props>(), {
- label: '',
- placeholder: '请选择日期范围',
- startTitle: '选择开始日期',
- endTitle: '选择结束日期',
- start: '',
- end: '',
- labelWidth: '140rpx',
- showLabel: true,
- clearable: true
- })
- // Emits 定义
- const emit = defineEmits<{
- (e: 'update:startValue', value: string): void
- (e: 'update:endValue', value: string): void
- }>()
- // 弹窗显示状态
- const showStartPicker = ref<boolean>(false)
- const showEndPicker = ref<boolean>(false)
- // 内部值
- const innerStartValue = ref<string>(props.startValue)
- const innerEndValue = ref<string>(props.endValue)
- // 显示文本
- const displayText = computed<string>(() => {
- if (props.startValue.length > 0 && props.endValue.length > 0) {
- return `${props.startValue} - ${props.endValue}`
- }
- return props.placeholder
- })
- // 确认开始日期
- const handleStartConfirm = (value: string): void => {
- emit('update:startValue', value)
- showStartPicker.value = false
- // 自动弹出结束日期选择
- setTimeout(() => {
- showEndPicker.value = true
- }, 300)
- }
- // 确认结束日期
- const handleEndConfirm = (value: string): void => {
- emit('update:endValue', value)
- showEndPicker.value = false
- }
- // 清除选择
- const handleClear = (): void => {
- emit('update:startValue', '')
- emit('update:endValue', '')
- innerStartValue.value = ''
- innerEndValue.value = ''
- }
- </script>
- <style lang="scss">
- .date-range-picker {
- .date-range-item {
- display: flex;
- flex-direction: row;
- align-items: center;
- margin-bottom: 24rpx;
- &.no-margin {
- margin-bottom: 0;
- }
- .date-range-label {
- display: flex;
- align-items: center;
- justify-content: flex-start;
- font-weight: 400;
- font-size: 28rpx;
- color: #6e7580;
- }
- .date-range-input-box {
- flex: 1;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- padding: 20rpx;
- background-color: #f5f7fa;
- border-radius: 8rpx;
- .date-range-input-text {
- font-weight: 400;
- font-size: 28rpx;
- color: #131415;
- flex: 1;
- &.placeholder {
- color: #999999;
- }
- }
- .date-range-input-icons {
- display: flex;
- flex-direction: row;
- align-items: center;
- margin-left: 20rpx;
- .date-range-input-clear {
- width: 28rpx;
- height: 28rpx;
- margin-right: 12rpx;
- }
- .date-range-input-arrow {
- width: 24rpx;
- height: 24rpx;
- }
- }
- }
- }
- }
- </style>
|