Vue3中如何监听window.location.href的变化?
监听window.location.href变化的解决方案
为什么你的尝试无效
window.location是浏览器原生对象,不属于Vue的响应式系统范畴——Vue的ref/toRef只能追踪自身包装对象的属性变更,无法监听原生DOM对象的属性变化,因为原生对象的属性更新不会触发Vue的getter/setter拦截逻辑。
一、基于Vue Router的SPA场景(推荐)
如果你的SPA使用Vue Router,直接利用其内置的响应式路由对象即可,无需手动监听location:
import { useRoute, watch } from 'vue' export default function useNavigationList() { const route = useRoute() // 监听路由变化(对应href的更新) watch(route, (newRoute) => { console.log('当前href:', window.location.href) console.log('当前路由路径:', newRoute.path) // 在这里执行你的业务更新逻辑 }, { immediate: true, deep: true }) }
useRoute()返回的是响应式路由对象,路由切换时会自动触发watch回调immediate: true可让回调在组件初始化时立即执行一次- 若仅关心href值,直接在回调中读取
window.location.href即可
二、原生浏览器场景(无Vue Router)
如果是纯原生环境或未使用Vue Router,需要监听浏览器popstate事件(处理前进/后退),同时重写history.pushState和history.replaceState方法(这两个方法不会触发popstate),实现完整的href变化监听:
import { ref, watch, onUnmounted } from 'vue' export default function useNavigationList() { const currentHref = ref(window.location.href) // 处理前进/后退触发的href变化 const handlePopState = () => { currentHref.value = window.location.href } // 重写history方法,手动触发href更新 const originalPushState = history.pushState const originalReplaceState = history.replaceState const wrapHistoryMethod = (method) => { return function(...args) { const result = method.apply(this, args) currentHref.value = window.location.href return result } } history.pushState = wrapHistoryMethod(originalPushState) history.replaceState = wrapHistoryMethod(originalReplaceState) // 监听响应式的currentHref变化 watch(currentHref, (newHref) => { console.log('href已更新:', newHref) // 执行你的业务更新逻辑 }, { immediate: true }) // 组件卸载时恢复原生方法,移除事件监听 onUnmounted(() => { history.pushState = originalPushState history.replaceState = originalReplaceState window.removeEventListener('popstate', handlePopState) }) return { currentHref } }
- 用
ref维护当前href值,通过事件和重写方法更新该ref,让Vue能追踪变化 - 必须在组件卸载时恢复原生history方法,避免影响其他页面逻辑
popstate事件会在用户点击浏览器前进/后退按钮时触发
内容的提问来源于stack exchange,提问作者Zalo
相关产品推荐
相关产品推荐

