hookehuyr

feat(router): 添加路由滚动行为和页面回顶功能

确保路由切换和页面激活时立即滚动到顶部,避免用户感知到过渡延迟
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()
......