feat(日历组件): 添加清空选中日期功能并优化日期切换按钮显示
在日历组件中添加清空选中日期的功能,并优化日期切换按钮的显示样式和文本 当有选中日期时显示具体日期,无选中日期时显示"切换日期" 添加清空按钮用于快速清除当前选中状态
Showing
2 changed files
with
54 additions
and
4 deletions
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-01-25 15:34:17 | 2 | * @Date: 2025-01-25 15:34:17 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2026-01-22 20:26:40 | 4 | + * @LastEditTime: 2026-01-22 20:44:20 |
| 5 | * @FilePath: /mlaj/src/components/calendar/CollapsibleCalendar.vue | 5 | * @FilePath: /mlaj/src/components/calendar/CollapsibleCalendar.vue |
| 6 | * @Description: 可折叠日历组件 | 6 | * @Description: 可折叠日历组件 |
| 7 | --> | 7 | --> |
| ... | @@ -29,7 +29,7 @@ | ... | @@ -29,7 +29,7 @@ |
| 29 | <div class="calendar-date-display" @click="expandCalendar"> | 29 | <div class="calendar-date-display" @click="expandCalendar"> |
| 30 | <div class="calendar-date-main">{{ formattedCurrentDate }}</div> | 30 | <div class="calendar-date-main">{{ formattedCurrentDate }}</div> |
| 31 | <div class="calendar-weekday">{{ formattedWeekday }}</div> | 31 | <div class="calendar-weekday">{{ formattedWeekday }}</div> |
| 32 | - <div class="text-xs text-gray-500 mt-1 collapsible-text p-1 bg-white w-20 text-center rounded-full border border-gray-200">切换日期</div> | 32 | + <div class="text-xs text-gray-500 mt-1 collapsible-text px-3 py-1 bg-white text-center rounded-full border border-gray-200 inline-block min-w-[5rem] max-w-[8rem]">{{ toggleButtonText }}</div> |
| 33 | </div> | 33 | </div> |
| 34 | <!-- <div class="calendar-action"> | 34 | <!-- <div class="calendar-action"> |
| 35 | <div class="calendar-action-text">指定日期</div> | 35 | <div class="calendar-action-text">指定日期</div> |
| ... | @@ -63,6 +63,13 @@ | ... | @@ -63,6 +63,13 @@ |
| 63 | @close="collapseCalendar" | 63 | @close="collapseCalendar" |
| 64 | > | 64 | > |
| 65 | <div class="calendar-popup-content"> | 65 | <div class="calendar-popup-content"> |
| 66 | + <button | ||
| 67 | + v-if="hasSelectedDate" | ||
| 68 | + class="absolute top-3 right-3 z-10 text-xs px-3 py-1 rounded-full border border-green-600 text-green-600 bg-white" | ||
| 69 | + @click.stop="clearSelectedDate" | ||
| 70 | + > | ||
| 71 | + 清空 | ||
| 72 | + </button> | ||
| 66 | <van-calendar | 73 | <van-calendar |
| 67 | ref="calendarRef" | 74 | ref="calendarRef" |
| 68 | :poppable="false" | 75 | :poppable="false" |
| ... | @@ -144,11 +151,15 @@ const props = defineProps({ | ... | @@ -144,11 +151,15 @@ const props = defineProps({ |
| 144 | subtaskList: { | 151 | subtaskList: { |
| 145 | type: Array, | 152 | type: Array, |
| 146 | default: () => [] | 153 | default: () => [] |
| 154 | + }, | ||
| 155 | + hasSelectedDate: { | ||
| 156 | + type: Boolean, | ||
| 157 | + default: false | ||
| 147 | } | 158 | } |
| 148 | }) | 159 | }) |
| 149 | 160 | ||
| 150 | // Emits定义 | 161 | // Emits定义 |
| 151 | -const emit = defineEmits(['update:modelValue', 'select', 'click-subtitle', 'panel-change', 'select-course']) | 162 | +const emit = defineEmits(['update:modelValue', 'select', 'click-subtitle', 'panel-change', 'select-course', 'clear-date']) |
| 152 | 163 | ||
| 153 | // 响应式数据 | 164 | // 响应式数据 |
| 154 | const isExpanded = ref(false) | 165 | const isExpanded = ref(false) |
| ... | @@ -321,6 +332,13 @@ const formattedWeekday = computed(() => { | ... | @@ -321,6 +332,13 @@ const formattedWeekday = computed(() => { |
| 321 | return weekdays[dayjs(currentDate.value).day()] | 332 | return weekdays[dayjs(currentDate.value).day()] |
| 322 | }) | 333 | }) |
| 323 | 334 | ||
| 335 | +const toggleButtonText = computed(() => { | ||
| 336 | + if (!props.hasSelectedDate) return '切换日期' | ||
| 337 | + const date_val = props.modelValue || currentDate.value | ||
| 338 | + const text = dayjs(date_val).format('YYYY-MM-DD') | ||
| 339 | + return `选中 ${text}` | ||
| 340 | +}) | ||
| 341 | + | ||
| 324 | /** | 342 | /** |
| 325 | * 展开日历 | 343 | * 展开日历 |
| 326 | */ | 344 | */ |
| ... | @@ -366,6 +384,17 @@ const onPanelChange = (panel) => { | ... | @@ -366,6 +384,17 @@ const onPanelChange = (panel) => { |
| 366 | emit('panel-change', panel) | 384 | emit('panel-change', panel) |
| 367 | } | 385 | } |
| 368 | 386 | ||
| 387 | +const clearSelectedDate = () => { | ||
| 388 | + const today = new Date() | ||
| 389 | + currentDate.value = today | ||
| 390 | + if (calendarRef.value && typeof calendarRef.value.reset === 'function') { | ||
| 391 | + calendarRef.value.reset(today) | ||
| 392 | + } | ||
| 393 | + emit('update:modelValue', today) | ||
| 394 | + emit('clear-date') | ||
| 395 | + collapseCalendar() | ||
| 396 | +} | ||
| 397 | + | ||
| 369 | // 监听modelValue变化 | 398 | // 监听modelValue变化 |
| 370 | watch(() => props.modelValue, (newValue) => { | 399 | watch(() => props.modelValue, (newValue) => { |
| 371 | if (newValue) { | 400 | if (newValue) { |
| ... | @@ -592,6 +621,7 @@ defineExpose({ | ... | @@ -592,6 +621,7 @@ defineExpose({ |
| 592 | } | 621 | } |
| 593 | 622 | ||
| 594 | .calendar-popup-content { | 623 | .calendar-popup-content { |
| 624 | + position: relative; | ||
| 595 | height: 100%; | 625 | height: 100%; |
| 596 | overflow: hidden; | 626 | overflow: hidden; |
| 597 | 627 | ... | ... |
| ... | @@ -15,11 +15,13 @@ | ... | @@ -15,11 +15,13 @@ |
| 15 | :title="taskDetail.title" | 15 | :title="taskDetail.title" |
| 16 | :formatter="formatter" | 16 | :formatter="formatter" |
| 17 | :subtask-list="taskDetail.subtask_list" | 17 | :subtask-list="taskDetail.subtask_list" |
| 18 | + :has-selected-date="hasUserSelectedDate" | ||
| 18 | v-model="selectedDate" | 19 | v-model="selectedDate" |
| 19 | @select="onSelectDay" | 20 | @select="onSelectDay" |
| 20 | @click-subtitle="onClickSubtitle" | 21 | @click-subtitle="onClickSubtitle" |
| 21 | @panel-change="onPanelChange" | 22 | @panel-change="onPanelChange" |
| 22 | @select-course="onSelectCourse" | 23 | @select-course="onSelectCourse" |
| 24 | + @clear-date="onClearSelectedDate" | ||
| 23 | /> | 25 | /> |
| 24 | </div> | 26 | </div> |
| 25 | 27 | ||
| ... | @@ -335,6 +337,24 @@ const selectedDate = ref(new Date()); | ... | @@ -335,6 +337,24 @@ const selectedDate = ref(new Date()); |
| 335 | const hasUserSelectedDate = ref(!!route.query.date) | 337 | const hasUserSelectedDate = ref(!!route.query.date) |
| 336 | const isInitializing = ref(true) | 338 | const isInitializing = ref(true) |
| 337 | 339 | ||
| 340 | +const onClearSelectedDate = () => { | ||
| 341 | + const next_query = { ...route.query } | ||
| 342 | + delete next_query.date | ||
| 343 | + router.replace({ | ||
| 344 | + path: route.path, | ||
| 345 | + query: next_query | ||
| 346 | + }) | ||
| 347 | + | ||
| 348 | + hasUserSelectedDate.value = false | ||
| 349 | + selectedDate.value = dayjs().format('YYYY-MM-DD') | ||
| 350 | + getTaskDetail(dayjs().format('YYYY-MM')) | ||
| 351 | + | ||
| 352 | + page.value = 0 | ||
| 353 | + checkinDataList.value = [] | ||
| 354 | + finished.value = false | ||
| 355 | + onLoad(null, false) | ||
| 356 | +} | ||
| 357 | + | ||
| 338 | const onSelectDay = (day) => { | 358 | const onSelectDay = (day) => { |
| 339 | const currentSelectedDate = dayjs(day).format('YYYY-MM-DD'); | 359 | const currentSelectedDate = dayjs(day).format('YYYY-MM-DD'); |
| 340 | 360 | ||
| ... | @@ -394,7 +414,7 @@ const onSelectCourse = (course) => { | ... | @@ -394,7 +414,7 @@ const onSelectCourse = (course) => { |
| 394 | checkinDataList.value = [] | 414 | checkinDataList.value = [] |
| 395 | finished.value = false | 415 | finished.value = false |
| 396 | // 重新加载数据 | 416 | // 重新加载数据 |
| 397 | - onLoad(route.query.date, hasUserSelectedDate.value) | 417 | + onLoad(hasUserSelectedDate.value ? (route.query.date || selectedDate.value) : null, hasUserSelectedDate.value) |
| 398 | } | 418 | } |
| 399 | 419 | ||
| 400 | /** | 420 | /** | ... | ... |
-
Please register or login to post a comment