vue-router@4、history.state和标记第一层路由的方法

原创
08/22 09:59
阅读数 17

在之前的文章(标记本次浏览的第一个页面)中提到vue-router会在history.state中存放一个字符串来标识路由,这一点在文档中没有明说它的原理,我们在利用history.state来标记第一层路由的时候需要对vue-router的这一数据进行特殊的处理。

vue-router@4

但是在新的vue-router@4中,我们不需要对history.state进行特殊的处理,反而可以利用vue-router存放在其中的数据来标记第一层路由。

在vue-router@4的文档中有这样一段描述(history.state的用法

Vue Router 将信息保存在 history.state 上。如果你有任何手动调用 history.pushState() 的代码,你应该避免它,或者用的 router.push() 和 history.replaceState() 进行重构。原因:我们使用历史状态来保存导航信息,如滚动位置,以前的地址等。

也就是是说vue-router@4明确的说明了,路由信息是保存在history.state中的。

history.state

我们用vue-cli创建一个vue@3的项目来看一个例子,如果我们直接打开网址(比如从VSCode的控制台按Ctrl进入http://localhost:8080),在浏览器的控制台打印history.state,可以看到输出为:

{
    back: null
    current: "/"
    forward: null
    position: 0
    replaced: true
    scroll: null
}

这些就是vue-router存放的路由信息,其中:

  • back:上一层路由地址
  • current:当前路由地址
  • forward:下一层路由地址
  • position:当前路由在历史记录中的位置
  • replaced:是否是替换路由
  • scroll:页面位置信息

在源码中其类型被定义为:

interface StateEntry extends HistoryState {
    back: HistoryLocation | null
    current: HistoryLocation
    forward: HistoryLocation | null
    position: number
    replaced: boolean
    scroll: _ScrollPositionNormalized | null | false
}

且我们可以看到它是这样被初始化的:

{
    back: null,
    current: currentLocation.value,
    forward: null,
    // the length is off by one, we need to decrease it
    position: history.length - 1,
    replaced: true,
    // don't add a scroll as the user may have an anchor and we want
    // scrollBehavior to be triggered without a saved position
    scroll: null,
}

也就是说position是当前路由历史长度减一,如果这是浏览器打开的第一个页面,路由历史长度为1,那么当前路由位置就是0。以此我们可以判断这是进入页面的第一层路由。

position不为0的时候,比如先打开浏览器,在输入http://localhost:8080时,由于浏览器初始页面也算是一层路由,position就为1。

{
    back: null
    current: "/"
    forward: "/about"
    position: 1
    replaced: true
    scroll: {left: 0, top: 0}
}

此时我们可以通过判断back是否为null来判断是否是第一层路由。因为vue-router随他可以取得浏览器历史的位置,但无法获取其他页面的路径。而在自身的路由体系内,路径都是可以拿到的。因为,back === null就以为这当前处于这个SPA的第一层路由。

总结

在vue-router@4中,我们可以通过:

window.history.state.position === 0 || window.history.state.back === null

来判断当前路由是否是本次SPA浏览的第一层路由。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部