feat(checkin): 动态调整日历高度以适应不同屏幕尺寸
添加响应式布局功能,根据窗口尺寸和设备类型计算日历高度 移除组件时清理事件监听器
Showing
1 changed file
with
69 additions
and
4 deletions
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-05-29 15:34:17 | 2 | * @Date: 2025-05-29 15:34:17 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-06-13 14:12:53 | 4 | + * @LastEditTime: 2025-06-13 14:23:31 |
| 5 | * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue | 5 | * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| 8 | <template> | 8 | <template> |
| 9 | <AppLayout :hasTitle="false"> | 9 | <AppLayout :hasTitle="false"> |
| 10 | <van-config-provider :theme-vars="themeVars"> | 10 | <van-config-provider :theme-vars="themeVars"> |
| 11 | - <van-calendar ref="myRefCalendar" :title="taskDetail.title" :poppable="false" :show-confirm="false" :style="{ height: '24rem' }" | 11 | + <van-calendar ref="myRefCalendar" :title="taskDetail.title" :poppable="false" :show-confirm="false" :style="{ height: calendarHeight }" |
| 12 | switch-mode="year-month" color="#4caf50" :formatter="formatter" row-height="50" :show-mark="false" | 12 | switch-mode="year-month" color="#4caf50" :formatter="formatter" row-height="50" :show-mark="false" |
| 13 | @select="onSelectDay" | 13 | @select="onSelectDay" |
| 14 | @click-subtitle="onClickSubtitle"> | 14 | @click-subtitle="onClickSubtitle"> |
| ... | @@ -163,7 +163,7 @@ | ... | @@ -163,7 +163,7 @@ |
| 163 | </template> | 163 | </template> |
| 164 | 164 | ||
| 165 | <script setup> | 165 | <script setup> |
| 166 | -import { ref, onBeforeUnmount } from 'vue' | 166 | +import { ref, onBeforeUnmount, onMounted, computed } from 'vue' |
| 167 | import { useRoute, useRouter } from 'vue-router' | 167 | import { useRoute, useRouter } from 'vue-router' |
| 168 | import { showConfirmDialog, showSuccessToast, showFailToast, showLoadingToast } from 'vant'; | 168 | import { showConfirmDialog, showSuccessToast, showFailToast, showLoadingToast } from 'vant'; |
| 169 | import AppLayout from "@/components/layout/AppLayout.vue"; | 169 | import AppLayout from "@/components/layout/AppLayout.vue"; |
| ... | @@ -181,13 +181,75 @@ useTitle(route.meta.title); | ... | @@ -181,13 +181,75 @@ useTitle(route.meta.title); |
| 181 | 181 | ||
| 182 | const myRefCalendar = ref(null); | 182 | const myRefCalendar = ref(null); |
| 183 | 183 | ||
| 184 | +// 窗口尺寸相关的响应式数据 | ||
| 185 | +const windowHeight = ref(window.innerHeight); | ||
| 186 | +const windowWidth = ref(window.innerWidth); | ||
| 187 | + | ||
| 188 | +/** | ||
| 189 | + * 动态计算日历高度 | ||
| 190 | + * 根据屏幕尺寸和设备类型自适应调整 | ||
| 191 | + */ | ||
| 192 | +const calendarHeight = computed(() => { | ||
| 193 | + // 获取可视窗口高度 | ||
| 194 | + const viewportHeight = windowHeight.value; | ||
| 195 | + | ||
| 196 | + // 预留给其他内容的空间(头部、底部等) | ||
| 197 | + const reservedSpace = 200; // 可根据实际需要调整 | ||
| 198 | + | ||
| 199 | + // 计算可用高度 | ||
| 200 | + const availableHeight = viewportHeight - reservedSpace; | ||
| 201 | + | ||
| 202 | + // 设置最小和最大高度限制 | ||
| 203 | + const minHeight = 300; // 最小高度 | ||
| 204 | + const maxHeight = 500; // 最大高度 | ||
| 205 | + | ||
| 206 | + // 根据屏幕宽度调整高度比例 | ||
| 207 | + let heightRatio = 0.6; // 默认占可用高度的55% | ||
| 208 | + | ||
| 209 | + if (windowWidth.value < 375) { | ||
| 210 | + // 小屏手机 | ||
| 211 | + heightRatio = 0.45; | ||
| 212 | + } else if (windowWidth.value < 414) { | ||
| 213 | + // 中等屏幕手机 | ||
| 214 | + heightRatio = 0.42; | ||
| 215 | + } else if (windowWidth.value >= 768) { | ||
| 216 | + // 平板或更大屏幕 | ||
| 217 | + heightRatio = 0.35; | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | + const calculatedHeight = Math.floor(availableHeight * heightRatio); | ||
| 221 | + | ||
| 222 | + // 确保高度在合理范围内 | ||
| 223 | + const finalHeight = Math.max(minHeight, Math.min(maxHeight, calculatedHeight)); | ||
| 224 | + | ||
| 225 | + return `${finalHeight}px`; | ||
| 226 | +}); | ||
| 227 | + | ||
| 228 | +/** | ||
| 229 | + * 监听窗口尺寸变化 | ||
| 230 | + */ | ||
| 231 | +const handleResize = () => { | ||
| 232 | + windowHeight.value = window.innerHeight; | ||
| 233 | + windowWidth.value = window.innerWidth; | ||
| 234 | +}; | ||
| 235 | + | ||
| 236 | +// 组件挂载时添加事件监听 | ||
| 237 | +onMounted(() => { | ||
| 238 | + window.addEventListener('resize', handleResize); | ||
| 239 | + // 监听屏幕方向变化(移动端) | ||
| 240 | + window.addEventListener('orientationchange', () => { | ||
| 241 | + // 延迟更新,等待方向变化完成 | ||
| 242 | + setTimeout(handleResize, 100); | ||
| 243 | + }); | ||
| 244 | +}); | ||
| 245 | + | ||
| 184 | // 存储所有视频播放器的引用 | 246 | // 存储所有视频播放器的引用 |
| 185 | const videoPlayers = ref([]); | 247 | const videoPlayers = ref([]); |
| 186 | 248 | ||
| 187 | // 存储所有音频播放器的引用 | 249 | // 存储所有音频播放器的引用 |
| 188 | const audioPlayers = ref([]); | 250 | const audioPlayers = ref([]); |
| 189 | 251 | ||
| 190 | -// 组件卸载前清理播放器引用 | 252 | +// 组件卸载前清理播放器引用和事件监听器 |
| 191 | onBeforeUnmount(() => { | 253 | onBeforeUnmount(() => { |
| 192 | // 停止所有视频和音频播放 | 254 | // 停止所有视频和音频播放 |
| 193 | if (videoPlayers.value) { | 255 | if (videoPlayers.value) { |
| ... | @@ -204,6 +266,9 @@ onBeforeUnmount(() => { | ... | @@ -204,6 +266,9 @@ onBeforeUnmount(() => { |
| 204 | if (videoPlayers.value) videoPlayers.value = []; | 266 | if (videoPlayers.value) videoPlayers.value = []; |
| 205 | if (audioPlayers.value) audioPlayers.value = []; | 267 | if (audioPlayers.value) audioPlayers.value = []; |
| 206 | 268 | ||
| 269 | + // 清理事件监听器 | ||
| 270 | + window.removeEventListener('resize', handleResize); | ||
| 271 | + window.removeEventListener('orientationchange', handleResize); | ||
| 207 | }); | 272 | }); |
| 208 | 273 | ||
| 209 | 274 | ... | ... |
-
Please register or login to post a comment