History库源码分析-createLocation
2023-11-15 11:30:36createLocation(current: string | Location, to: To, state: any = null, key?: string)
返回一个带有唯一值key的location对象。
当前方法是一个公共方法,在createBrowserHistory/createHashHistory/createMemoryHistory中都使用其创建location对象。
Location interface
interface Locationextends Path { state: State; key: string; }
Path interface
interface Path { pathname: string; search: string; hash: string; }
To interface
interface To = Partial
方法参数
- current: 当前的pathname或者location对象,当是一个string时,代表pathname,如果是一个对象,表示location对象
- to: 新的location对象,将要跳转的路由location对象
- state: 表示状态对象,调用时
- key: 唯一值
内部逻辑
createLocation内部代码其实很简单。
pathname: 表示当前url pathname,当current是一个string时,代表pathname,直接返回给pathname,如果是一个对象,表示location对象, 返回location.pathname。如果不被to中的pathname覆盖,将起作用。
hash/search如果不被to覆盖的话,默认是""
to可以是一个对象,对象中包含pathname、hash、search,也可以是一个string,如果是一个字符串,将会通过parsePath对字符串进行解析,解析后返回一个包含pathname、hash、search的对象。通过to产生的包含pathname、hash、search的对象,会覆盖默认的pathname/hash/search。
state取至参数state
key: 唯一值,如果在这个浏览器标签中,第一次打开项目时,执行createBrowserHistory/createHashHistory时,生成的location中的key值是"default",其他情况下通过Math.random().toString(36).substr(2, 8)生成的随机值。
key取值优先级:
- to.key
- 参数key
- createKey(): 随机数,通过Math.random().toString(36).substr(2, 8)生成
使用场景
当createBrowserHistory执行后,会返回一个history对象,在history对象上有一个属性location,这个属性代表当前历史记录的location对象。当我们通过history.location访问当前历史记录location对象时,这个会调用:
return createLocation( "", { pathname, search, hash }, // state defaults to "null" because "window.history.state" does (globalHistory.state && globalHistory.state.usr) || null, (globalHistory.state && globalHistory.state.key) || "default" );
pathname, search, hash,这三个值来源:
const { pathname, search, hash } = window.location;
当createHashHistory执行后,会返回一个history对象,在history对象上有一个属性location,这个属性代表当前历史记录的location对象。当我们通过history.location访问当前历史记录location对象时,这个会调用:
return createLocation( "", { pathname, search, hash }, // state defaults to "null" because "window.history.state" does (globalHistory.state && globalHistory.state.usr) || null, (globalHistory.state && globalHistory.state.key) || "default" );
pathname, search, hash,这三个值来源:
let { pathname = "/", search = "", hash = "" } = parsePath(window.location.hash.substr(1));
当执行history.push或者history.replace时,会通过这个方法来获取新的location对象。
源码
export function createLocation(
current: string | Location,
to: To,
state: any = null,
key?: string
): Readonly<Location> {
let location: Readonly<Location> = {
pathname: typeof current === "string" ? current : current.pathname,
search: "",
hash: "",
...(typeof to === "string" ? parsePath(to) : to),
state,
key: (to && (to as Location).key) || key || createKey(),
};
return location;
}