You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 15:57:16