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

NuxtJS中路由切换时如何检测路由方向(前进/后退)?

解决Nuxt中手机返回键关闭菜单而非跳转页面的问题

首先先指出你代码里的几个关键问题:

  1. 事件注册时错误执行了函数:window.addEventListener('popstate', closeMenuOnRouteBack()) 里的括号会让函数立即执行,而非绑定监听,应该改成 closeMenuOnRouteBack(不带括号)
  2. 错误调用了navigator.preventDefault():需要通过事件对象调用preventDefault(),函数要接收event参数
  3. popstate事件本身不区分前进/后退,得自己通过历史栈或路由状态判断操作方向

下面是两种可行的修正方案:


方案一:通过维护历史栈状态判断后退

这种方法通过手动管理浏览器历史栈,确保菜单打开时用户按返回键先触发菜单关闭:

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'

const isMenuVisible = ref(false)
let initialHistoryLength = 0

function closeMenuOnRouteBack(event) {
  // 通过历史栈长度变化判断是否为后退操作
  if (window.history.length < initialHistoryLength) {
    if (isMenuVisible.value) {
      isMenuVisible.value = false
      // 恢复历史栈长度,避免页面跳转
      history.pushState(null, '', window.location.href)
      event.preventDefault()
    }
  }
  // 更新历史栈基准长度
  initialHistoryLength = window.history.length
}

// 打开菜单时同步添加历史记录
const openMenu = () => {
  isMenuVisible.value = true
  history.pushState(null, '', window.location.href)
  initialHistoryLength = window.history.length
}

onMounted(() => {
  initialHistoryLength = window.history.length
  // 正确绑定事件(传递函数引用)
  window.addEventListener('popstate', closeMenuOnRouteBack)
})

onBeforeUnmount(() => {
  window.removeEventListener('popstate', closeMenuOnRouteBack)
})
</script>

方案二:利用Vue Router导航守卫判断方向

基于Nuxt的Vue Router内置状态,直接判断路由操作是否为后退:

<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'

const isMenuVisible = ref(false)
const router = useRouter()

router.beforeEach((to, from) => {
  // 通过路由状态判断是否为后退操作
  const isBackAction = router.options.history.state?.back
  if (isBackAction && isMenuVisible.value) {
    isMenuVisible.value = false
    // 取消路由跳转
    return false
  }
})
</script>

内容的提问来源于stack exchange,提问作者Mehmet Ali KOÇAL

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 04:05:58