feat(router): 添加路由滚动行为和页面回顶功能
确保路由切换和页面激活时立即滚动到顶部,避免用户感知到过渡延迟
Showing
2 changed files
with
39 additions
and
2 deletions
| 1 | /* | 1 | /* |
| 2 | * @Date: 2025-10-30 10:29:15 | 2 | * @Date: 2025-10-30 10:29:15 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-11-04 20:35:35 | 4 | + * @LastEditTime: 2025-11-04 20:52:25 |
| 5 | * @FilePath: /stdj_h5/src/router/index.js | 5 | * @FilePath: /stdj_h5/src/router/index.js |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | */ | 7 | */ |
| ... | @@ -53,6 +53,16 @@ const routes = [ | ... | @@ -53,6 +53,16 @@ const routes = [ |
| 53 | const router = createRouter({ | 53 | const router = createRouter({ |
| 54 | history: createWebHashHistory('/index.html'), | 54 | history: createWebHashHistory('/index.html'), |
| 55 | routes, | 55 | routes, |
| 56 | + /** | ||
| 57 | + * 路由切换时的滚动行为 | ||
| 58 | + * 说明:不使用平滑滚动,进入新页面时立即滚动到顶部,确保用户无感知的快速回到初始位置。 | ||
| 59 | + */ | ||
| 60 | + scrollBehavior(to, from, savedPosition) { | ||
| 61 | + if (savedPosition) { | ||
| 62 | + return savedPosition | ||
| 63 | + } | ||
| 64 | + return { left: 0, top: 0 } | ||
| 65 | + } | ||
| 56 | }) | 66 | }) |
| 57 | 67 | ||
| 58 | // 路由守卫 | 68 | // 路由守卫 | ... | ... |
| ... | @@ -156,7 +156,7 @@ | ... | @@ -156,7 +156,7 @@ |
| 156 | </template> | 156 | </template> |
| 157 | 157 | ||
| 158 | <script setup> | 158 | <script setup> |
| 159 | -import { ref, computed, nextTick, onMounted, watch } from 'vue' | 159 | +import { ref, computed, nextTick, onMounted, onActivated, watch } from 'vue' |
| 160 | import VideoPlayer from '@/components/VideoPlayer.vue' | 160 | import VideoPlayer from '@/components/VideoPlayer.vue' |
| 161 | import { useTitle } from '@vueuse/core'; | 161 | import { useTitle } from '@vueuse/core'; |
| 162 | import { useRouter } from 'vue-router' | 162 | import { useRouter } from 'vue-router' |
| ... | @@ -238,6 +238,24 @@ const calculateLinePosition = async () => { | ... | @@ -238,6 +238,24 @@ const calculateLinePosition = async () => { |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | /** | 240 | /** |
| 241 | + * 确保页面滚动位置在顶部(进入或激活时立即回顶) | ||
| 242 | + * 说明:使用立即滚动(非平滑)以避免过渡被用户察觉。 | ||
| 243 | + */ | ||
| 244 | +const ensurePageScrollTop = () => { | ||
| 245 | + if (typeof window !== 'undefined') { | ||
| 246 | + // 立即滚动到顶部 | ||
| 247 | + window.scrollTo({ top: 0, behavior: 'auto' }) | ||
| 248 | + } | ||
| 249 | + // 兜底处理,兼容部分浏览器 | ||
| 250 | + if (document && document.documentElement) { | ||
| 251 | + document.documentElement.scrollTop = 0 | ||
| 252 | + } | ||
| 253 | + if (document && document.body) { | ||
| 254 | + document.body.scrollTop = 0 | ||
| 255 | + } | ||
| 256 | +} | ||
| 257 | + | ||
| 258 | +/** | ||
| 241 | * 点击切换步骤状态并更新底部箭头位置 | 259 | * 点击切换步骤状态并更新底部箭头位置 |
| 242 | * @param {number} index 选中步骤索引 | 260 | * @param {number} index 选中步骤索引 |
| 243 | */ | 261 | */ |
| ... | @@ -256,6 +274,8 @@ const mastersList = ref([]) | ... | @@ -256,6 +274,8 @@ const mastersList = ref([]) |
| 256 | 274 | ||
| 257 | // 组件挂载后计算装饰线位置 | 275 | // 组件挂载后计算装饰线位置 |
| 258 | onMounted(async () => { | 276 | onMounted(async () => { |
| 277 | + // 进入页面时立即回到顶部 | ||
| 278 | + ensurePageScrollTop() | ||
| 259 | await calculateLinePosition(); | 279 | await calculateLinePosition(); |
| 260 | // 调用接口获取首页数据 | 280 | // 调用接口获取首页数据 |
| 261 | const { code, list } = await homePageAPI(); | 281 | const { code, list } = await homePageAPI(); |
| ... | @@ -293,10 +313,17 @@ onMounted(async () => { | ... | @@ -293,10 +313,17 @@ onMounted(async () => { |
| 293 | updateCarouselPosition(false) | 313 | updateCarouselPosition(false) |
| 294 | // 初始化底部箭头位置 | 314 | // 初始化底部箭头位置 |
| 295 | updateArrowPosition() | 315 | updateArrowPosition() |
| 316 | + // 列表内容渲染后再兜底回顶一次,避免外部干扰 | ||
| 317 | + ensurePageScrollTop() | ||
| 296 | }) | 318 | }) |
| 297 | } | 319 | } |
| 298 | }) | 320 | }) |
| 299 | 321 | ||
| 322 | +// 组件被 keep-alive 激活时,立即回到顶部 | ||
| 323 | +onActivated(() => { | ||
| 324 | + ensurePageScrollTop() | ||
| 325 | +}) | ||
| 326 | + | ||
| 300 | // 监听当前步骤变化,重新计算装饰线位置 | 327 | // 监听当前步骤变化,重新计算装饰线位置 |
| 301 | watch(currentStep, () => { | 328 | watch(currentStep, () => { |
| 302 | calculateLinePosition() | 329 | calculateLinePosition() | ... | ... |
-
Please register or login to post a comment