vue-router剖析
路由
路由最早由后端提出,用于根据不同的请求返回不同的页面。大致流程如下:
- 浏览器发出请求
- 服务器监听到端口有请求过来
- 根据服务器的路由配置,返回相应信息(可以是html、json、图片等)
- 浏览器根据数据包的
Context-Type
来决定如何解析
前端路由
随着ajax
的流行,异步数据请求交互在不刷新浏览器的情况下运行。而异步交互体验的高级版本就是SPA-单页应用。单页应用不仅仅是在页面交互是无刷新的,连页面跳转都是无刷新的,为了实现单页应用,所以就有了前端路由。类似于后端路由,前端路由就是匹配不同的url路径进行解析,然后动态渲染html内容。
hash模式
https://www.xxx.com/#/hash
这种#
后面hash
值得变化,并不会触发新的请求,因此也不会刷新页面。每次hash
值的变化都会触发hashchange
事件,通过这个事件就可以知道更新哪些页面内容
window.onhashchange = e => {
console.log(e.oldURL, e.newURL)
const hash = location.hash.slice(1)
app.innerHTML = hash
}
history模式
https://www.xxx.com/login
随着HTML5的发布,带来了两个新的API:pushState
和replaceState
,通过这两个API可以改变url地址且不会发送请求。同时还有popstate
事件用来监听url的改变。使用history模式,url就不会出现丑陋的#
,url也变得比较美观。
通过history api去掉了丑陋的#
,但也存在问题:不怕前进/后退,就怕刷新。因为刷新是去请求服务器的,在hash
下,前端路由修改的是#之后的内容,在发送请求时是不会带上的,但在history下可以自由地修改路径、参数,当刷新时,如果服务器中没有相应的响应或资源,容易爆404
vue-router核心原理
通过
new VueRouter
中的mode
参数来选择使用那种路由模式在
router
中使用current
保存当前url作为一个插件,大部分功能都在
install
函数中完成在
install
中使用Vue.mixin
注入的beforeCreate
来给组件添加全局唯一的router
实例(挂载在根组件上,其余组件通过$parent._routerRoot._router
挂载)使用
popstate
或hashchange
两个事件来监听url变化(针对于手动输入url)并设置current
使用
Vue.util.defineReactive(this, '_route', this._router.history.current)
来使router
变为响应式current变化 👉 重新渲染
router-view
中的组件解析路由配置从而可以更加便利地找到url所对应的页面
Array<{ name: component }>
👇
Map<{ name: component }>
实现
<router-link></router-link>
和<router-view / >
两个组件
总结
vue-router
以插件方式侵入Vue
,从而支持一个额外的router
属性,以提供监听并改变组件路由数据的能力,这样每次路由发生变化后,可以同步到数据,从而响应式地触发组件的更新