vue-router原理

800 阅读1分钟

vue-router有几种模式?

三种模式,"hash" | "history" | "abstract",其中浏览器环境默认为hash,Node.js 环境默认为abstract

  • hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器。
  • history: 依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式
  • abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式。

基本原理

$router的push和replace是手动调用内部路径切换方法transitionTo,go、back、forward方法实际调用的是window.history.go(),以及浏览器的前进后退会触发相应的监听事件,然后调用transitionTo,之后更新路由,触发<router-view> 的重新渲染。

  • hash模式是优先监听popstate事件,不行就降级为hashchange事件,history模式监听popstate事件;
  • history.pushState()和history.replaceState()修改浏览器历史栈后url改变但不会刷新页面,不会触发popstate事件;
  • window.location.hash = '#/b'修改hash不会刷新页面,会触发hashchange事件,hash的改变会自动添加到浏览器历史记录中;

执行流程

  1. 点击 router-link或执行$router.push()
  2. 调用this.history.push,不同模式下该函数的实现略有不同,以下以hash模式为例,
  3. 先执行 this.transitionTo 做路径切换,在切换完成的回调函数中,执行 pushHash 函数;
    • pushHash 优先用pushState ,不行就降级为window.location.hash = path
    • pushState 会调用浏览器原生的 history 的 pushState 接口或者 replaceState 接口,更新浏览器的 url 地址,并把当前 url 压入历史栈中。
  4. updateRoute ,更新 this.apps 保存的组件实例的 _route 值
  5. 重新渲染组件
    • 通过Vue.mixin()方法,全局注册一个混合,影响注册之后所有创建的每个Vue实例,该混合在beforeCreate钩子中通过Vue.util.defineReactive()定义了响应式的_route属性。所谓响应式属性,即当_route值改变时,会自动调用Vue实例的render()方法,更新视图。

参考