https://www.jianshu.com/p/4295aec31302

随着前端应用的业务功能越来越复杂、用户对于使用体验的要求越来越高,单页应用(SPA)成为前端应用的主流形式。大型单页应用最显著特点之一就是采用前端路由系统,通过改变URL,在不重新请求页面的情况下,更新页面视图。
请在这里输入引用内容
“更新视图但不重新请求页面”是前端路由原理的核心之一,目前在浏览器环境中这一功能的实现主要有两种方式:
1.利用URL中的hash(“#”)
2.利用History interface在 HTML5中新增的方法

//hash模式
www.7evenlee/shop/#/login
//history interface模式
www.7evenlee/shop/login
//请求的是同一个页面

在路由设置时有一个mode参数,决定使用哪种方式的路由
mode 参数:
1.默认hash
2.history 注:如果浏览器不支持history新特性,则采用hash方式
3.如果不在浏览器环境则使用abstract(node环境下)
//Vue-router源码
switch (mode) {
case 'history':
this.history = new HTML5History(this, options.base)
break
case 'hash':
this.history = new HashHistory(this, options.base, this.fallback)
break
case 'abstract':
this.history = new AbstractHistory(this, options.base)
break
default:
if (process.env.NODE_ENV !== 'production') {
assert(false, invalid mode: ${mode})
}
}

HashHistory模式

有两个方法,一个是push(),一个是replace()

push()将新路由添加到浏览器访问历史的栈顶

push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
  this.transitionTo(location, route => {
    pushHash(route.fullPath)
    onComplete && onComplete(route)
  }, onAbort)
}

function pushHash (path) {
  window.location.hash = path
}

从设置路由改变到视图更新的流程:
1 $router.push() //调用方法
2 HashHistory.push() //根据hash模式调用,设置hash并添加到浏览器历史记录(添加到栈顶)(window.location.hash=XXX)
3 History.transitionTo() //监测更新,更新则调用History.updateRoute()
4 History.updateRoute() //更新路由
5 {app._route= route} //替换当前app路由
6 vm.render() //更新视图
##replace() 将参数传入的路由替换掉当前路由

replace (location: RawLocation, onComplete?: Function, onAbort?: Function) {
  this.transitionTo(location, route => {
    replaceHash(route.fullPath)
    onComplete && onComplete(route)
  }, onAbort)
}

function replaceHash (path) {
  const i = window.location.href.indexOf('#')
  window.location.replace(
    window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path
  )
}
//其实就是通过window.location.href来截取字符串替换修改地址

HTML5History模式

History interface是浏览器历史记录栈提供的接口,包括back(),forward(),go()等方法,可以读取浏览器当前历史记录栈的信息,进行跳转操作。
HTML5开始,又新增了pushState(),replaceState(),可以对浏览器历史记录栈进行修改

window.history.pushState(stateObject, title, URL)
window.history.replaceState(stateObject, title, URL)

1.stateObject:当浏览器跳转到新状态,将触发popState事件,携带这个stateObject参数的副本
2.title:所添加记录的标签
3.url:所添加记录的URL

1.push()

与hash模式类似,不过不是window.hash,是history.pushState

2.replace()

与hash模式类似,不过不是window.replace,是history.replaceState

3.监听地址的变化

在HTML5History的构造函数中监听popState(window.onpopstate)

关于H5中window的新增API
https://blog.csdn.net/qq_40028324/article/details/83268502

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

pushState通过stateObject可以添加任意类型的数据到记录中;而hash只可添加短字符串

pushState可额外设置title属性供后续使用

history模式则会将URL修改得就和正常请求后端的URL一样,如后端没有配置对应/user/id的路由处理,则会返回404错误