Vue3中Router push异常:页面动画仅F5刷新后生效
Vue3路由跳转后滚动动画失效的解决方案
问题根源
直接通过URL访问/home后,再用router.push跳转回该路径时,Vue的组件复用机制会导致滚动动画的初始化逻辑未触发——硬加载(URL输入/F5刷新)时组件会重新挂载,动画代码正常执行,但单页路由切换时组件可能并未重新初始化,且滚动事件监听可能未正确绑定或执行。
修复方案
1. 绑定动画逻辑到组件生命周期钩子
在/home页面组件中,利用Vue的生命周期钩子确保每次路由进入时都执行动画初始化,同时管理滚动事件的监听:
<script setup> import { onMounted, onActivated, onUnmounted } from 'vue' const scrollEvent = function() { // 先重置所有section的动画状态,避免重复触发 const itemList = document.querySelectorAll('.mainsection .section') itemList.forEach(section => { section.classList.add('animatable') section.classList.remove('animated') }) // 执行滚动检测逻辑 const scroll = window.innerHeight + window.scrollY itemList.forEach(section => { if(section.offsetTop < scroll) { section.classList.remove('animatable') section.classList.add('animated') } }) } // 初次挂载时绑定监听并执行一次 onMounted(() => { scrollEvent() window.addEventListener('scroll', scrollEvent) }) // 路由切换回该组件时(组件复用场景)重新执行动画初始化 onActivated(() => { scrollEvent() // 强制滚动到顶部,避免之前的滚动位置干扰动画触发 window.scrollTo(0, 0) }) // 组件卸载时移除监听,防止内存泄漏 onUnmounted(() => { window.removeEventListener('scroll', scrollEvent) }) </script>
2. 配置路由滚动行为
在路由配置中添加scrollBehavior,确保每次路由切换时页面滚动到顶部,避免残留的滚动位置导致动画判断异常:
// router/index.js import { createRouter, createWebHistory } from 'vue-router' const router = createRouter({ history: createWebHistory(), routes: [ // 你的路由配置 ], scrollBehavior() { // 跳转新路由时自动滚动到页面顶部 return { top: 0 } } }) export default router
3. 替换DOM查询为Vue响应式引用(可选优化)
避免直接操作DOM,改用Vue的ref来获取section元素,让逻辑更符合Vue的响应式机制:
<template> <div class="mainsection"> <section class="section animatable" ref="sectionRefs"></section> <section class="section animatable" ref="sectionRefs"></section> <!-- 更多section --> </div> </template> <script setup> import { ref, onMounted, onActivated, onUnmounted } from 'vue' const sectionRefs = ref([]) const scrollEvent = () => { const scroll = window.innerHeight + window.scrollY sectionRefs.value.forEach(section => { if(section.offsetTop < scroll) { section.classList.remove('animatable') section.classList.add('animated') } else { // 滚动回上方时恢复动画初始状态 section.classList.add('animatable') section.classList.remove('animated') } }) } // 生命周期钩子逻辑同方案1 onMounted(() => { scrollEvent() window.addEventListener('scroll', scrollEvent) }) onActivated(() => { scrollEvent() window.scrollTo(0, 0) }) onUnmounted(() => { window.removeEventListener('scroll', scrollEvent) }) </script>
内容的提问来源于stack exchange,提问作者bxeom
相关产品推荐
相关产品推荐

