首先history是干嘛的:
history
允许您轻松地管理JavaScript运行的任何地方的会话历史。history
对象抽象出各种环境中的差异,并提供一个最小的API,允许您管理history
堆栈、导航和持久化会话之间的状态。
接下来我们来看看history
有哪些api可以使用
import {
createBrowserHistory
createHashHistory
createMemoryHistory
createPath
parsePath } from 'history'
首先我们需要先来了解一下前端路由监听的几种方式
hash
:主要是基于锚点的原理实现。browser
:即使用html5
标准中的history api
通过监听popstate
事件来对dom
进行操作。每次路由变化都会引起重定向memory
:这种实现是在内存中维护一个堆栈用于管理访问历史的方式,比较复杂。在早起移动端使用比较多。实现麻烦,问题也较多。现在很少有使用。RN
在使用这种路由模式static
:主要用于ssr
。需要后端去管理路由
通过hash改变,利用window.onhashchange 监听。调用
history.pushState()
或者history.replaceState()
不会触发popstate事件.popstate
事件只会在浏览器某些行为下触发, 比如点击后退、前进按钮(或者在JavaScript中调用history.back()、history.forward()、history.go()
方法),此外,a 标签的锚点也会触发该事件.当网页加载时,各浏览器对
popstate
事件是否触发有不同的表现,Chrome 和 Safari会触发popstate
事件, 而Firefox不会.history.pushState(state, title, url)
意思就是把一个history记录插入到历史记录中history.replaceState(state, title, url)
用新的state和URL替换当前。不会造成页面刷新。
createBrowserHistory
浏览器历史记录将位置存储在常规url中。这是的标准 *大多数web应用程序,但它需要在服务器上进行一些配置,以确保您 *在多个url上提供相同的应用程序
- 初始化工作
首先新创建的历史对象的默认动作为POP
然后它会创建2个事件队列listeners
和blockers
function createEvents() {
var handlers = [];
return {
get() { return handlers.length },
push(fn) {
handlers.push(fn)
},
call(arg) {
handlers.forEach((h) => h && h(arg))
}
}
}
通过window.history
和window.location
获取浏览器当前会话的信息,如果此时的序列号(index)为0,说明浏览器重新渲染了当前页面,通过window.history.replaceState
给当前的history添加状态信息idx(初始化值为0);
最后注册一个监听事件,window.addEventListener('popstate', handlePop);
- 开始监听操作
如果这个时候blockers
事件队列(handlers)为空的时候,否则调用listeners
事件队列, 它的核心是applyTx方法
function applyTx(nextAction: Action) {
action = nextAction;
[index, location] = getIndexAndLocation();
listeners.call({ action, location });
}
createHashHistory
同时监听window.addEventListener('popstate', handlePop)
和window.addEventListener('hashchange', handlePop)
createMemoryHistory
内存历史记录在内存中存储当前位置。它是为使用而设计的
*在有状态的非浏览器环境,如tests
和React Native
。
参考地址
history库的地址 [github.com/ReactTraini…]
History的MDN[developer.mozilla.org/zh-CN/docs/…]