NuxtJS中路由切换时如何检测路由方向(前进/后退)?
解决Nuxt中手机返回键关闭菜单而非跳转页面的问题
首先先指出你代码里的几个关键问题:
- 事件注册时错误执行了函数:
window.addEventListener('popstate', closeMenuOnRouteBack())里的括号会让函数立即执行,而非绑定监听,应该改成closeMenuOnRouteBack(不带括号) - 错误调用了
navigator.preventDefault():需要通过事件对象调用preventDefault(),函数要接收event参数 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
相关产品推荐
相关产品推荐

