History库源码分析-createLocation

2023-11-15 11:30:36

createLocation(current: string | Location, to: To, state: any = null, key?: string)

返回一个带有唯一值key的location对象。

当前方法是一个公共方法,在createBrowserHistory/createHashHistory/createMemoryHistory中都使用其创建location对象。

Location interface
interface Location extends 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内部代码其实很简单。

  1. pathname: 表示当前url pathname,当current是一个string时,代表pathname,直接返回给pathname,如果是一个对象,表示location对象, 返回location.pathname。如果不被to中的pathname覆盖,将起作用。

  2. hash/search如果不被to覆盖的话,默认是""

  3. to可以是一个对象,对象中包含pathname、hash、search,也可以是一个string,如果是一个字符串,将会通过parsePath对字符串进行解析,解析后返回一个包含pathname、hash、search的对象。通过to产生的包含pathname、hash、search的对象,会覆盖默认的pathname/hash/search。

  4. state取至参数state

  5. 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)生成

使用场景


  1. 当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;
    
  2. 当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));
    
  3. 当执行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;
}

目录

相关推荐
为什么更多前端应用偏向于单页面应用路由模式-原生historyHistory库源码分析-parsePathHistory库源码分析-Action动作类型路由模式-hash