超详细的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是编译时输出接口;
欢迎加入前端沟通群,大家一起学习
更多推荐
所有评论(0)