必须手动触发首次渲染,因hashchange事件在页面初次加载带hash的url时不会触发,需在domcontentloaded或onload中主动读取location.hash并执行路由函数。

必须手动触发首次渲染,否则页面加载时不会执行路由逻辑。因为 hashchange 事件只在用户点击或脚本修改 location.hash 后才触发,https://example.com/#/user 这种带 hash 的 URL 初次打开时,事件根本不会响。
监听 hashchange 但页面首次加载不触发?
这是最常踩的坑:只绑了 window.addEventListener('hashchange', handler),却没处理初始状态。
- 页面加载完成时,
location.hash已存在(比如#/about),但hashchange不会自动触发 - 必须在初始化阶段主动读取并执行一次:用
location.hash.slice(1)去掉#,再调用你的路由函数,例如router.go(location.hash.slice(1) || '/') - 推荐在
DOMContentLoaded或window.onload里做这一步,而不是等hashchange自己来
改 hash 时该用 location.hash = 'xxx' 还是 document.location.href = '#xxx'?
用 window.location.hash = '/xxx',别碰 document.location.href。
-
document.location.href = '#/xxx'会额外添加一条历史记录,导致前进/后退多出无效项 -
window.location.hash = '/xxx'行为明确、语义清晰,且只更新 hash 部分,不会影响 pathname 或 search - 注意:赋值时不用加
#,window.location.hash的 setter 会自动补上
hashchange 事件对象里的 oldURL 和 newURL 怎么用?
它们能帮你判断跳转方向或做防重复渲染,但要注意兼容性边界。
-
event.oldURL和event.newURL是完整 URL 字符串(含协议、域名、路径、hash),不是纯 hash 值 - 提取当前 hash 应始终用
location.hash,而不是从event.newURL解析 —— 因为首次加载没事件,且 IE8 不支持这两个字段 - 如果你需要区分“前进”还是“后退”,不能只靠
oldURL/newURL,得自己维护一个历史栈或用history.state配合
能不能一边用 hashchange,一边偷偷调用 pushState?
不能。Hash 路由和 History 路由是互斥机制,混用会导致路由丢失。
-
hashchange只响应#后面的部分变化;改pathname或search但不动hash,它完全无感 - 如果代码里同时有
window.location.hash = '/a'和history.pushState(...),浏览器实际只更新了 hash,pushState调用会被忽略(或静默失败) - 想升级到 history 模式,必须彻底移除所有
hashchange监听、location.hash操作,并统一走popstate+pushState
真正容易被忽略的是:hash 路由的“可预测性”全依赖你对 location.hash 的读写一致性。一旦某个地方用 href="#/x" 跳转,另一个地方用 location.replace('#/x'),就可能破坏历史栈顺序 —— 这类细节不会报错,但会让后退行为变得不可控。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











