一、window.history.pushState
1.说明
window.history.pushState方法用于向浏览器历史栈中添加一个状态。
2.语法:
window.history.pushState(state, title, url);
3.参数说明:
- state:一个对象,用于保存状态信息,可以通过history.state属性获取该状态信息。
- title:一个字符串,表示新的页面标题,目前大部分浏览器忽略该参数。
- url:一个字符串,表示新的URL,可以是绝对路径或相对路径。
4.使用示例:
window.history.pushState({page: 1}, "Page 1", "page1.html");
上述示例将一个新的状态对象{page: 1}添加到浏览器历史栈中,并且将浏览器URL修改为"page1.html"。
5.注意事项:
- 调用pushState方法不会触发页面的刷新或跳转,只会修改浏览器URL和添加一个新的状态对象。
- 修改URL后,可以通过window.onpopstate事件监听浏览器的前进后退操作,并根据新的状态对象进行相应的处理。
- 使用pushState方法后,可以通过浏览器的前进后退按钮或JavaScript代码的history.back()、history.forward()等方法进行页面的切换。
6.state传参
可以通过state参数来实现路由传参。state参数可以是一个对象,可以在对象中添加需要传递的参数。
例如,假设我们需要在路由中传递一个id参数,可以这样使用:
window.history.pushState({id: 1}, "Page 1", "page1.html");
上述示例中,我们将一个包含id参数的对象{id: 1}作为state参数传递给pushState方法。
在接收参数的页面中,可以通过history.state来获取传递的参数:
js
console.log(history.state.id); // 输出 1
上述示例中,我们通过history.state.id来获取传递的id参数。
注意,使用pushState方法传递参数并不会触发页面的刷新或跳转,只会修改浏览器URL和添加一个新的状态对象。因此,在接收参数的页面中,需要通过监听浏览器的前进后退操作来处理参数的变化。可以通过window.onpopstate事件来监听浏览器的前进后退操作,并根据新的状态对象进行相应的处理。
二、history.pushState和Vue Router对比
1.共同点:
window.history.pushState和Vue Router都可以用于实现前端路由。
2.区别:
-
window.history.pushState是浏览器原生提供的API,用于修改浏览器URL和添加一个新的状态对象到浏览器历史栈中。它可以实现无刷新的页面切换,并且可以传递参数。但是,它只提供了基本的路由功能,需要手动监听浏览器的前进后退操作,并进行相应的处理。
-
Vue Router是Vue.js官方提供的路由插件,它提供了更丰富的路由功能和组件化的路由配置。它可以通过定义路由表、嵌套路由、动态路由等方式来配置路由,并且提供了路由导航守卫、路由过渡效果等功能。Vue Router可以更方便地管理页面的切换和传递参数,并且与Vue.js框架的其他特性更加紧密地结合在一起。
3.总结
window.history.pushState适用于简单的前端路由场景,而Vue Router适用于复杂的单页面应用(SPA)场景。如果项目使用Vue.js框架,推荐使用Vue Router来管理路由。
三、Vue Router 中 history 源码分析
1.说明:
Vue Router中的history路由跳转是通过调用浏览器原生的history.pushState方法实现的。
2.源码中的位置:
- 在Vue Router的源码中,当进行路由跳转时,会调用push方法来进行跳转,该方法定义在src/history/base.js文件中:
js
export function push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
const { current: fromRoute } = this
// ...
const to = resolve(location, fromRoute, false, this)
const { location: toRoute, route: toRouteRecord } = to
const pushUrl = stringifyQuery(toRoute.fullPath)
if (this.app) {
const { scrollBehavior } = this.app.$options
if (scrollBehavior) {
handleScroll(this.router, toRoute, fromRoute, false)
}
}
this.confirmTransition(
to,
() => {
const { state } = this.history
// ...
this.transitionTo(toRoute, () => {
pushState(cleanPath(this.base + pushUrl), onComplete, onAbort)
})
},
err => {
if (isNavigationFailure(err, NavigationFailureType.redirected) && err.to === this.current.fullPath) {
// ...
return
}
if (onAbort) {
onAbort(err)
}
}
)
}
在上述代码中,首先通过resolve方法将目标路由转换为实际的路由对象to。然后,调用stringifyQuery方法将目标路由的query参数转换为URL字符串。接着,通过pushState方法将新的URL添加到浏览器历史栈中。
- pushState方法的具体实现可以在src/history/html5.js文件中找到:
js
function pushState (url?: string, replace?: boolean) {
const history = window.history
try {
if (replace) {
// ...
history.replaceState(state, '', url)
} else {
// ...
history.pushState(state, '', url)
}
} catch (e) {
// ...
}
}
- 在上述代码中,通过调用history.pushState方法将新的URL添加到浏览器历史栈中。通过replace参数来控制是使用pushState还是replaceState方法,replace为true时使用replaceState方法,replace为false时使用pushState方法。
3.Vue Router 中路由传参的quary和param的区别
1)说明:
在Vue Router中,路由传参可以使用query和params两种方式。
2)使用方式:
-
query参数是通过URL中的查询字符串传递的,
-
即在URL后面添加?param1=value1¶m2=value2。
-
query参数可以在路由跳转时通过route.query对象获取,也可以在组件中通过this.route.query获取。
-
params参数是通过URL路径中的占位符传递的,
-
即在路由配置中使用/:param1/:param2的形式定义。
-
params参数可以在路由跳转时通过route.params对象获取,也可以在组件中通过this.route.params获取。
3)区别:
传递方式不同:
- query参数通过URL中的查询字符串传递,
- params参数通过URL路径中的占位符传递。
使用方式不同:
- query参数可以在route.query对象或this.route.query获取,
- params参数可以在route.params对象或this.route.params获取。 传递的数据类型不同:
- query参数可以传递任意类型的数据,
- params参数一般用于传递动态路由参数,一般为字符串类型。
URL的形式不同:
- query参数的URL形式为?key1=value1&key2=value2,
- params参数的URL形式为/param1/param2。
总结:query参数适合传递较少的参数,而params参数适合传递较多或者动态的参数。