放肆青春的博客
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)

放肆青春

一个前端菜鸟的技术成长之路
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)
  • 前端

    • 前端 概览
    • 前端汇总

    • front 博文

    • front 项目总结

    • front 高级

    • front tools

  • vue

    • vue 概览
    • vue 汇总

    • vue 博文

      • vue对比
      • vue-router
        • 三种路由模式
          • 原理
          • 1. hash 模式
          • 2. history 模式
          • 3. abstract 模式
          • hash 模式和 history 模式区别
        • 三种路由守卫
          • 完整的导航解析流程
          • 全局路由守卫
          • 路由独享守卫
          • 组件内路由守卫
        • 其它问题
          • route 和 router 有什么区别?
          • vue-router 跳转和 location.href 有什么区别
      • vuex
      • vue2生命周期
      • vue组件通信
      • vue修饰符
      • vue异步组件
      • vue插槽
      • vue2 hook
    • vue 项目总结

    • vue 高级

  • html

    • html 概览
    • html 汇总

    • html 博文

  • css

    • css 概览
    • css 汇总

    • css 博文

    • sass

    • less

  • js

    • javascript 概览
    • JS 汇总

    • ES6

    • JS 博文

    • JS 工具

  • node

    • node 概览
    • node 汇总

    • node 框架

    • node 博文

  • react

    • react 概览
    • react 汇总

    • react 博文

    • react 高级

  • 微信小程序

    • 微信小程序 概览
    • 微信小程序总结
    • 微信小程序文章
    • 微信小程序 博文

    • 微信小程序 高级

  • 微信公众号

    • 微信公众号 概览
    • 微信公众号总结
    • 微信公众号文章
  • 多端开发

    • 多端开发
    • dsbridge 概览
    • jsbridge 概览
    • webview
    • uniapp

      • uniapp 概览
    • taro

      • taro 概览
    • flutter

      • flutter 概览
      • flutter 环境搭建
    • electron

      • electron 概览
  • front
放肆青春
2020-07-13

vue-router

# 三种路由模式

vue-router 默认是 hash 模式

  1. hash 模式

  2. history 模式

  3. abstract 模式

vue-router 在不支持 history 模式的浏览器 , 会自动会退到 hash 模式。(源码是通过 fallback 进行降级处理)

# 原理

vue-router 原理主要分成两部分,一部分是安装,另一个是实现数据监控和页面跳转。

    1. 安装

通过混入 beforeCreate 实现路由的绑定和监听操作。初始化 router。调用 Vue 工具类方法 defineReactive,当 router 发生改变时,页面能及时响应更新。最后通过 registerInstance 来实现对 router-view 的挂载操作。

(1)混入 beforeCreate(实现路由的绑定和监听操作)和 destoryed 方法;

(2)全局挂载$router和$route;

(3)注册 router-link 和 router-view 两个组件。

    1. 数据监控和页面跳转

路由更新 -> 视图。路由发生变化(hash 有 hashChange 监听方法,history 有 popstate),改变浏览器里的地址,再更新视图。采用 hash 或者 history 的路由模式,前端实现路由跳转。history 模式中,主要通过 pushstate、replaceState、go 实现,它们负责改变浏览器的路由,但是不跳转,这就实现了前端的路由,而 popstate 是监听方法,处理路由改变后,前端页面的显示问题。就是用栈来实现。

# 1. hash 模式

利用 URL 中的 hash("#");

'#' 和后面 URL 片段标识符被称为 hash, 可通过 window.location.hash 属性读取.

hash 虽然出现在 url 中,但不会被包括在 http 请求中,它是用来指导浏览器动作的,对服务器端完全无用,因此,改变 hash 不会重新加载页面。

使用 window.addEventListener("hashchange", fun) 监听路由的变化,然后使用 transitionTo(功能是路由跳转) 方法更新视图

每一次改变 hash(window.location.hash),都会在浏览器访问历史中增加一个记录。

利用 hash 的以上特点,就可以来实现前端路由"更新视图但不重新请求页面"的功能了。

  1. HashHistory.push()

原理: 通过 Vue.mixin()方法,全局注册一个混合,影响注册之后所有创建的每个 Vue 实例,该混合在 beforeCreate 钩子中通过 Vue.util.defineReactive()定义了响应式的_route 属性。所谓响应式属性,即当\_route 值改变时,会自动调用 Vue 实例的render()方法,更新视图。

顺序:\$router.push()-->HashHistory.push()-->History.transitionTo()-->History.updateRoute()-->{app.\_route=route}-->vm.render()

  1. HashHistory.replace()

原理: 调用 window.location.replace 方法将路由进行替换

  1. 监听地址栏

hash 值的改变会触发 hashchange 事件

上面的 VueRouter.push()和 VueRouter.replace()是可以在 vue 组件的逻辑代码中直接调用的,除此之外在浏览器中,用户还可以直接在浏览器地址栏中输入改变路由,因此还需要监听浏览器地址栏中路由的变化 ,并具有与通过代码调用相同的响应行为,在 HashHistory 中这一功能通过 setupListeners 监听 hashchange 实现:

需要注意的是调用 history.pushState()或 history.replaceState()不会触发 popstate 事件。只有在做出浏览器动作时,才会触发该事件,如用户点击浏览器的回退按钮(或者在 Javascript 代码中调用 history.back()或者 history.forward()方法)

# 2. history 模式

主要 HTML5 History API

使用 history.back(), history.forward()和 history.go() 方法来完成在用户历史记录中向后和向前的跳转。等操作会主动触发 popstate 事件

HTML5 History API 方法:

  1. pushState 添加历史记录条目

  2. replaceState 修改历史记录条目

  3. popstate 当活动的历史记录项发生变化时, popstate 事件都会被传递给 window 对象

  4. go() 用 go() 方法载入到会话历史中的某一特定页面, 通过与当前页面相对位置来标志 (当前页面的相对位置标志为 0)

window.history.go(-1); // 向后移动一个页面

window.history.go(1); // 向前移动一个页面

  1. back() 在 history 中向后跳转

# 3. abstract 模式

abstract 模式没有使用浏览器 api,可以放到 node 环境或者桌面应用中。

# hash 模式和 history 模式区别

  1. url 不同: hash 带#,histary 不带#

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

  3. 兼容性: hash 兼容 IE8 以上,history 兼容 IE10 以上 ,hash 支持低版本浏览器和 IE 浏览器,history 模式下需要支持 H5 的浏览器,使用的是 H5 的 api

  4. 底层监听的事件不一样

hash 模式: window.addEventListener('hashChange', function() { // ... });

history 模式:window.addEventListener('popstate', function() { // ... });

  1. 第三种路由模式 Abstract: 支持所有 javascript 运行模式。如果发现没有浏览器的 API,路由会自动强制进入这个模式。

# 三种路由守卫

# 完整的导航解析流程

  • 导航被触发。
  • 在失活的组件里调用 beforeRouteLeave 守卫。
  • 调用全局的 beforeEach 守卫。
  • 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  • 在路由配置里调用 beforeEnter。
  • 解析异步路由组件。
  • 在被激活的组件里调用 beforeRouteEnter。
  • 调用全局的 beforeResolve 守卫 (2.5+)。
  • 导航被确认。
  • 调用全局的 afterEach 钩子。
  • 触发 DOM 更新。
  • 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

# 全局路由守卫

  1. 全局前置守卫 beforeEach
const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})
1
2
3
4
5

参数:

to: Route: 即将要进入的目标 路由对象

from: Route: 当前导航正要离开的路由

next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

  1. 全局解析守卫 beforeResolve

在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用

  1. 全局后置钩子 afterEach

# 路由独享守卫

  1. beforeEnter

# 组件内路由守卫

  1. beforeRouteEnter

在渲染该组件的对应路由被 confirm 前调用

  1. beforeRouteUpdate

在当前路由改变,但是该组件被复用时调用

  1. beforeRouteLeave

导航离开该组件的对应路由时调用

# 其它问题

# route 和 router 有什么区别?

# $route 是“路由信息对象”(是正在跳转的这个路由的局部对象),

包括 path,params,hash,query,fullPath,matched,name 等路由信息参数。

  • $route.path

    字符串,等于当前路由对象的路径,会被解析为绝对路径,如 "/home/news" 。

  • $route.params

    对象,包含路由中的动态片段和全匹配片段的键值对

  • $route.query

    对象,包含路由中查询参数的键值对。例如,对于 /home/news/detail/01?favorite=yes ,会得到$route.query.favorite == 'yes' 。

  • $route.router

    路由规则所属的路由器(以及其所属的组件)。

  • $route.matched

    数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。

  • $route.name

当前路径的名字,如果没有使用具名路径,则名字为空。

# $router 是“路由实例”对象

包括了路由的跳转方法,钩子函数,是 VueRouter 的一个对象,通过 Vue.use(VueRouter)和 VueRouter 构造函数得到一个 router 的实例对象

# vue-router 跳转和 location.href 有什么区别

  1. vue-router 进行路由更新,静态跳转,页面不会重新加载;location.href 会触发浏览器,页面重新加载一次

  2. vue-router 使用 diff 算法,实现按需加载,减少 dom 操作

更新时间: 2/19/2022, 4:10:36 PM
vue对比
vuex

← vue对比 vuex→

最近更新
01
前端权限管理
02-24
02
vue2指令
02-24
03
vue2 hook
02-24
更多文章>
Theme by Vdoing | Copyright © 2019-2022 放肆青春
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式