-
Notifications
You must be signed in to change notification settings - Fork 441
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vue-router 源码分析-History #55
Comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
在前两篇文章中, 分别介绍了
vue-router
的整体流程和组件, 对history
的细节没有具体分析, 这一篇就具体来分析下history
的实现.History 实例化
在整体流程一文中有提到, VueRouter 提供了
HTML5History
、HashHistory
以及AbstractHistory
三种方式. 在 VueRouter 实例化的同时, 会对 History 实例化, 源码在src/index.js
:从上述代码可以看出,
vue-router
提供了三种模式:mode
(默认)、history
和abstract
, 三者的区别见mode.在整体流程和组件一文中有提到, 所有的 History 类都是在
src/history/
目录下, 并且都继承自src/history/base.js
. 下面会分别作具体分析.HTML5History
HTML5History
是利用 HTML5 History 的 APIpushState/repaceState
来完成 URL 跳转而无须重新加载页面; 源码在src/history/html5.js
中:从上述代码可以看到,
history
模式是比较简单的:popstate
HashHistory
hash
模式是一种降级方案, 也是默认模式.history
模式存在兼容性问题, 但hash
模式是被所有浏览器支持的. 在[email protected]
中, 提供了fallback
属性用于history
模式下的降级处理, 详情见tag#v2.6.0 源码在src/history/hash.js
中:从代码可知, 与
HTML5History
不同, 并没有在constructor
中作hashchange
的监听,setupListeners
是在router.init
方法中调用的:是在
route
切换完成后的回调中设置的, 这是为了修复 vuejs/vue-router#725, 避免beforeEnter
是异步的情况下,beforeEnter
被调用两次.此外, 我们都知道可以通过
window.location.hash
来获取 url 的hash
部分, 但在getHash()
方法却没有使用, 这样处理的原因是低版本的 Firefox 会对 hash 进行编码, 具体见 Firefox automatically decoding encoded parameter in url, does not happen in IE.AbstractHistory
这种模式和浏览器无关, 一般用于 Node 端测试, 其实现也是最简单的:
该模式比较抽象, 仅用一个数组来模拟浏览器的历史记录, 通过位置变量来获取当前的记录.
三种模式的初始化就大致介绍完了, 现在看看浏览器的
history
改变会发生什么?history 改变
有两种方式可以改变浏览器的
history
:router-link
组件浏览器的
history
发生改变时, 会触发window
的相关的事件:hashchange
和popstate
.hash
模式下:history
模式下:在vue-router 源码分析-组件一文中, 已经介绍过
router-link
组件, 其事件绑定如下:当
event
触发时, 会调用router
的push/replace
来更新路由, 其实现在src/index.js
:这里可以看出, 会去调用各子类的对应实现.
在整体流程一文中大致介绍了
transitionTo
的处理流程, 但忽略了很多细节. 如果想了解更多细节, 请移步到 vue-router 源码分析-history,vue-router
的版本虽然不一样, 但整个过程大致是一样的.小结
vue-router
虽然提供了三种模式, 但是执行的整体流程差异不大, 最大的差异是在history
改变时的具体处理逻辑不同.The text was updated successfully, but these errors were encountered: