https://developer.mozilla.org/zh-CN/docs/Web/API/History/pushState
https://github.com/ReactTraining/history
https://github.com/ReactTraining/history#blocking-transitions
- 这个库可以方便管理你的浏览记录。
- 该包是 React Router 仅有的两大主要依赖之一(除去 React 本身),在不同的 Javascript 环境中,它提供多种不同的形式来实现对 session 历史的管理。
安装
cnpm install history --save
import createBrowserHistory from 'history/createBrowserHistory'
import { createBrowserHistory } from 'history';
history 是可变的
history 对象是可变的,因此建议从
class Comp extends React.Component {
componentWillReceiveProps(nextProps) {
// locationChanged 将为 true
const locationChanged = nextProps.location !== this.props.location
// INCORRECT,因为 history 是可变的所以 locationChanged 将一直为 false
const locationChanged = nextProps.history.location !== this.props.history.location
}
}
<Route component={Comp} />
使用
- “browser history” - 在特定 DOM 上的实现,使用于支持 HTML5 history API 的 web 浏览器中
- “hash history” - 在特定 DOM 上的实现,使用于旧版本的 web 浏览器中
- “memory history” - 在内存中的 history 实现,使用于测试或者非 DOM 环境中,例如 React Native
createBrowserHistory
使用 HTML5 历史 API 记录(pushState,replaceState和popstate事件)的
createBrowserHistory({
basename: '/m', // 基链接
//所有地址的基本网址。如果您的应用程序是从服务器上的子目录提供的,则需要将其设置为子目录。
//格式正确的基本名应该有一个前导斜线,但是结尾不能有斜线。
forceRefresh: false, // 是否强制刷新整个页面
keyLength: 6, // location.key的长度
// 用于确认导航的功能。默认使用 window.confirm。
getUserConfirmation: (message,callback) => callback(window.confirm(message)) // 跳转拦截函数
})
createHashHistory
使用 URL 的 hash 部分(即 window.location.hash )的
注意:Hash 历史记录不支持location.key或location.state。在以前的版本中,我们试图填补行为,但存在我们无法解决的边缘案例。 任何需要此行为的代码或插件都将无法使用。由于此技术仅用于支持传统浏览器,因此我们鼓励您配置服务器以便与
配合使用。
createHashHistory({
basename: '', // 所有位置的基本 URL,格式正确的基本名应该有一个前导斜线,但结尾不能有斜线。
// 用于确认导航的功能。默认使用 window.confirm。
getUserConfirmation: (message, callback) => callback(window.confirm(message)),
hashType: 'slash', // 用于 window.location.hash 的编码类型。可用的值是:
// "slash" - 创建像 #/ 和的 #/sunshine/lollipops hash 表 (默认)
// "noslash" - 创建像 # 和的 #sunshine/lollipops hash 表
// "hashbang" - 创建 “ajax crawlable” (由Google弃用)hash,如 #!/ 和 #!/sunshine/lollipops
});
createMemoryHistory (手机端)
used as a reference implementation and may also be used in non-DOM environments, like React Native or tests
createMemoryHistory({
initialEntries: ['/'], // 初始载入路径,和MemoryRouter中的initialEntries是一样的
initialIndex: 0, // initialEntries初始载入索引
keyLength: 6, // location.key的长度
getUserConfirmation: null // 路由跳转拦截函数
})
示例
const history = createHistory(); 创建历史对象
const location = history.location; 获取location对象
const unlisten = history.listen( (location, action) => {
console.log(location,action)
// location是location对象
// action是动作名称,比如 "PUSH"
} )
history.push('/a', { some: 'state' }) // 强制跳转
unlisten() // 监听解绑
history 对象
属性、方法总览
length
- (number 类型) history 堆栈的条目数action
- (string 类型) 当前的操作(PUSH, REPLACE, POP)location
- (object 类型) 当前的位置。location 会具有以下属性:- pathname - (string 类型) URL 路径
- search - (string 类型) URL 中的查询字符串
- hash - (string 类型) URL 的哈希片段
- state - (object 类型) 提供给例如使用push(path, state)操作将 location 放入堆栈时的特定 location 状态。只在浏览器和内存历史中可用。
push(path, [state])
- (function 类型) 在 history 堆栈添加一个新条目replace(path, [state])
- (function 类型) 替换在 history 堆栈中的当前条目go(n)
- (function 类型) 将 history 堆栈中的指针调整ngoBack()
- (function 类型) 等同于go(-1)goForward()
- (function 类型) 等同于go(1)block(prompt)
- (function 类型) 阻止跳转。(详见history 文档)。
createMemoryHistory中提供了额外的两个属性:
history.index 当前历史记录的索引
history.entries 历史记录
方法详解
listen
- 监听历史对象中的路径变化,当路径发生变化后执行回调函数,参数就是最新的路径对象
- history.listen 函数会返回一个 取消监听 的函数,我们可以在组件卸载的时候,调用它
constructor(props){
super(props);
this.unlisten = history.listen( (location, action) => {
console.log(location,action);
})
}
componentWillUnmount(){
this.unlisten && this.unlisten();
}
push
使用push可以将一条新的历史记录推送到历史堆栈中
history.push('/a');
history.push('/a', {name: 'jack'});
history.push({
pathname: '/a',
search: 'isShare=1&id=1',
state: {
name: 'jack'
}
});
replace
和push方法使用形式一样,replace的作用是取代当前历史记录
go
goBack
goForward
用来前进,history.goForward();
另外使用createMemoryHistory创建的history对象,有canGo方法,和go方法类似
使用history实现路由跳转警告
const unblock = history.block('Do you want to leave?');
上面这个用法,就是添加一个跳转提示信息,默认使用dom环境的window.confirm,所以如果使用非dom环境的createMemoryHistory就要使用getUserConfirmation方法实现
另外,除了传递一个字符串提示信息以外,还可以添加函数
const unblock = history.block( (location,action) => { return 'do you leave?' } )
可以通过直接调用,unblock(); 实现方法解绑