超详细的vue-router原理

前言
vueRouter是前端路由,在无需刷新页面的情况下更新视图。
vueRouter有两种模式:一种是Hash模式,一种是History模式。
分别就是在HTML5History,HashHistory两个类中实现的。

一、vue-router组成

vue-router组件有三个部分
1.link:即v-link
2.view:元素指令,即
3.router:核心部分

二、vue-router简单的一个流程

1.url 变化
2.history监听(onChange事件):window.addEventListener(‘hashchange’, () => {})
3.调用路由匹配( this._match):会保存老的transition和新的transition
4.走一遍路由守卫beforeEach
5.走startTransition开始进入transition的周期(也算是vue-router的核心所在)

     1).canReuse:调用canReuse钩子
          看当前的<vue-router>和将要跳转的<vue-router>之间有没有可重用的组件
          a/b/c
          a/b/d  =>  可复用[a,b],需要销毁[c],需要生成[d]
          
     2).canDeactivate(c):调用canDeactivate钩子
         route: {
             canDeactivate() {}
         }
         
     3).canActivate(d):调用canActivate钩子
     
     4).deactivate(c):调用deactivate钩子
     
     5)._afterEachHooks(c):调用afterEach钩子
     
     6).reuse([a,b]):调用data钩子
     
     7).activate(d) :调用activate | data钩子

6.若activate(d),则调用vue中的build方法,新生成component

三、vue-router的实现原理

1.hash模式,主要是hashHistory:hash(“#”)符号的本来作用是加在URL中指示网页中的位置,hash虽然出现在URL中,但不会被包括在HTTP请求中。它是用来指导浏览器动作的,对服务器端完全无用,因此,改变hash不会重新加载页面,每一次改变hash(window.location.hash),都会在浏览器的访问历史中增加一个记录,改变hash可以监听到hashchange事件:
window.addEventListener(“hashchange”, funcRef, false)
底层处理路由更新(push)的流程:
1)push方法 对window的hash直接赋值
window.location.hash = route.fullPath
2)router是怎么做到在每一个Vue组件中都能使用的呢?
在插件加载的地方,即VueRouter的install方法中通过Vue.mixin()全局注册一个混合,影响到每一个组件。

export function install (Vue) {
  
  Vue.mixin({
    beforeCreate () {
      if (isDef(this.$options.router)) {
        this._router = this.$options.router
        this._router.init(this)
        Vue.util.defineReactive(this, '_route', this._router.history.current)
      }
      registerInstance(this, this)
    },
  })
}

看代码我们知道Vue.mixin()在beforeCreate钩子中通过Vue.util.defineReactive()定义了响应式的route属性,所谓响应式其实就是,当route值改变时,调用Vue的render方法,更新视图

2.history模式,主要利用HTML5History
我们主要利用这个HTML5History来操作浏览器历史记录栈,主要方法有back(), forward(), go()来读取浏览器路由历史并控制跳转,HTML5新增pushState(), replaceState()2个方法来修改历史信息,调用这两个方法修改历史信息后,虽然当前URL改变了,但浏览器不会立即发送请求该URL,这就满足单页面应用”更新视图但不重新请求页面“的需求,修改浏览器历史记录后会触发popstate事件,我们可以通过监听popstate事件

两种模式的比较,history模式更有优势

1)hash模式有#,history模式没有#,更美观
2)pushState设置的新url是和当前url同源的任意url,hash模式只可以修改#后面的内容,也就是只可以设置与当前同文档的url
3)pushState设置的新url和当前url相同时也会把记录添加进记录栈中,而hash只有新的和当前的不同的时候才会添加到栈中
4)如果是history模式,他要匹配/,就匹配不到,就会报错

懒加载原理及懒加载实现的方式

什么是路由懒加载?
路由懒加载也可以叫做路由组件懒加载。懒加载也叫延迟加载,即在需要的时候进行加载,随用随载。

为什么需要懒加载?
首先,我们知道路由中通常会定义很多不同的页面,这个页面这项目build打包后,一般情况下,会放在一个单独的js文件中,如果很多的页面都放在同一个js文件中,必然会造成这个页面非常大。我们一次性的从服务器中请求下来这个页面,可能会花费一定时间,用户体验不好。这时候我们就需要懒加载了。

懒加载原理:
把不一样路由对应的组件分割成不一样的代码块,而后当路由被访问的时候才加载对应组件,这样就更加高效了。结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载.html。
vue异步组件:Vue 允许你以一个工厂函数的方式定义你的组件,Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
webpack代码分离方法有三种:
1)入口起点:使用 entry 配置手动地分离代码;
2)防止重复:使用 Entry dependencies 或者 SplitChunksPlugin 去重和分离 chunk。
3)动态导入:通过模块的内联函数调用来分离代码

懒加载实现方式:
Vue异步加载技术
1)最常用的是通过import()来实现它

//主要这句话
const router = new VueRouter({  
  routes: [   
   	  { path: '/about', 
   	  component:  () => import('./About.vue') }]
   })

2)component: resolve => require([‘放入需要加载的路由地址’], resolve)

{
    path: '/problem',
    name: 'problem',
    component: resolve => require(['../pages/home/problemList'], resolve)
}

require 和 import 引入依赖的区别
require是Commonjs的规范,node应用是由模块组成的,遵从commonjs的规
import是es6为js模块化提出的新的语法,import (导入)要与export(导出)结合使用
commonjs输出的,是一个值的拷贝,而es6输出的是值的引用;
commonjs是运行时加载,es6是编译时输出接口;

欢迎加入前端沟通群,大家一起学习
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值