- 初阶:
- hash:
http://example.com/#abc/bbc- 使用 
window.onhashchange监听变更事件,做出反应;直接修改页面hash,改变路由位置 - 不会带到服务端,无法做SSR
 - 不利于做 seo;失去原生页面锚点定位能力
 - 兼容IE8
 - 不需要兼容处理
 
 - 使用 
 - history: 
[http://example.com/abc/bbc](http://example.com/#abc/bbc)- 使用 HTML5 History Interface 的 
popState监听路由变化;使用 pushState()和replaceState()方法 - history 对服务端来说与普通url一致,可以做 ssr,容易做seo优化
 - history 可以携带 state 对象,hash只能带字符串
 - 兼容 IE10
 - 需要服务端做兼容处理
 
 - 使用 HTML5 History Interface 的 
 
 - hash:
 中阶:
history 依赖
popstate事件监听路由变化,但 pushState、replaceState 都不会触发这个事件,所以:- 监听所有 a 路由的click事件,拦截,调用 pushState 更改路由
 - 拦截 history 原生 pushState、replaceState 方法,为它们添加事件特性
const listener = function (type) {var orig = history[type];return function () {var rv = orig.apply(this, arguments);var e = new Event(type);e.arguments = arguments;window.dispatchEvent(e);return rv;};};window.history.pushState = listener('pushState');window.history.replaceState = listener('replaceState');
 
hashchange 事件只有在hash变化的时候才会触发,所以初始化时还需要额外监听 load 事件
// replaceState和pushState行为的监听initHistoryHook(cb: Function){let history:any = window.historylet bindHistoryEventListener = function(type: string){let originEvent = history[type]console.log('arguments', arguments, this)return function(){let newEvent = originEvent.apply(this, arguments)// 事件发生时就会触发这个回调cb(type, arguments)return newEvent}}history.pushState = bindHistoryEventListener('pushState')history.replaceState = bindHistoryEventListener('replaceState')}
