浅析vue-router原理

2020-06-12 21:21:45易采站长站整理

// Avoiding first `popstate` event dispatched in some browsers but first
// history route not updated since async guard at the same time.
// 避免在某些浏览器中首次发出“popstate”事件
// 由于同一时间异步监听,history路由没有同时更新。
const location = getLocation(this.base)
if (this.current === START && location === initLocation) {
return
}
this.transitionTo(location, route => {
if (supportsScroll) {
handleScroll(router, route, current, true)
}
})
})
}

hash模式仅改变hash部分的内容,而hash部分是不会包含在http请求中的(hash带#):

oursite.com/#/user/id //如请求,只会发送http://oursite.com/

所以hash模式下遇到根据url请求页面不会有问题

而history模式则将url修改的就和正常请求后端的url一样(history不带#)

oursite.com/user/id

如果这种向后端发送请求的话,后端没有配置对应/user/id的get路由处理,会返回404错误。

官方推荐的解决办法是在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。同时这么做以后,服务器就不再返回 404 错误页面,因为对于所有路径都会返回 index.html 文件。为了避免这种情况,在 Vue 应用里面覆盖所有的路由情况,然后在给出一个 404 页面。或者,如果是用 Node.js 作后台,可以使用服务端的路由来匹配 URL,当没有匹配到路由的时候返回 404,从而实现 fallback。

两种模式比较

一般的需求场景中,hash模式与history模式是差不多的,根据MDN的介绍,调用history.pushState()相比于直接修改hash主要有以下优势:

• pushState设置的新url可以是与当前url同源的任意url,而hash只可修改#后面的部分,故只可设置与当前同文档的url

• pushState设置的新url可以与当前url一模一样,这样也会把记录添加到栈中,而hash设置的新值必须与原来不一样才会触发记录添加到栈中

• pushState通过stateObject可以添加任意类型的数据记录中,而hash只可添加短字符串 pushState可额外设置title属性供后续使用

AbstractHistory

‘abstract’模式,不涉及和浏览器地址的相关记录,流程跟’HashHistory’是一样的,其原理是通过数组模拟浏览器历史记录栈的功能


//abstract.js实现,这里通过栈的数据结构来模拟路由路径
export class AbstractHistory extends History {
index: number;
stack: Array<Route>;

constructor (router: Router, base: ?string) {
super(router, base)
this.stack = [] this.index = -1
}