开发者社区> 廊桥梦醉> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

vue route实现原理

简介: 后端路由 路由的概念最开始是由后端提出来的,在以前用模板引擎开发页面的时候,经常会看到这样 http://www.xxx.com/login 大致流程可以看成这样: (1)浏览器发出请求 (2)服务器端监听到80端口或者443有请求过来,并解析url路径 (3)根据服务器的路由配置,返回相应信息(可以是html文件,json数据,也可以是图片) (4)浏览器根据数据包的content-type来决定如何解析数据 简单来说路由就是用来跟后端服务器进行交互的一种方式,通过不同的路径来请求不同的资源,请求不同的页面是路由的其中一项功能。
+关注继续查看

后端路由

路由的概念最开始是由后端提出来的,在以前用模板引擎开发页面的时候,经常会看到这样

http://www.xxx.com/login

大致流程可以看成这样:

(1)浏览器发出请求

(2)服务器端监听到80端口或者443有请求过来,并解析url路径

(3)根据服务器的路由配置,返回相应信息(可以是html文件,json数据,也可以是图片)

(4)浏览器根据数据包的content-type来决定如何解析数据

简单来说路由就是用来跟后端服务器进行交互的一种方式,通过不同的路径来请求不同的资源,请求不同的页面是路由的其中一项功能。

前端路由

1、hash模式

随着ajax流行,异步数据请求交互运行在不刷新浏览器的情况下。而异步交互体验的更高级版本就是SPA——单页面应用。单页面应用不仅仅是在页是无刷新的,连页面吧跳转也是无刷新的,为了实现单页面应用,所以就有了前端路由。

类似于服务端路由,前端路由实现起来其实其实也很简单,就是匹配不同的url路径,进行解析,然后动态的渲染出该区域的html内容,但是这样存在一个问题,就是url每次变化的时候,都会造成页面的刷新,那解决的思路便是在改变url的情况下,保证页面不刷新,早2014年之前,大家是通过has来实现路由,url hash就类似于http://www.xxx.com/#/login

这种#后面hash值的变化并不会导致浏览器向服务器发送请求,也就不会刷新页面,另外每次hash值的变化,还会触发hashchange事件,通过这个事件我们就可以知道hash值发生了改变,然后我们便可以监听hashchange来实现更新页面部分内容的操作:

img_84f6e82ed9f815054a3481faf4379c38.png

2.history模式

14年以后H5标准发布,多了两个API,pushState和replaceState,通过这两个api可以改变url地址且不会发送请求,同时还有popstate事件,通过这些就能够用另一种方式来实现前端路由,单原理都是跟hash实现相同,用了H5的实现单页面板路由的URL就不会多出来一个#,变得更加美观,但是因为没有了#,所以当用户刷新页面之类的操作的时候,浏览器还是会给服务器发送请求,为了避免出现这种情况,所以这个实现要拂去其端的支持,需要把所有路由都重定向到根页面

img_51bcefc381e2ffc131552e3ec91bab5a.png

vue route的实现er

我们来看一下vue-route是如何定义的:

import Vueroute from 'vue-router'

Vue,use(Vueroute)

const router = new Vueroute({

          mode:'history',

         routes:[....]

})

new Vue({

            router

            .......

})

可以看出vue-router是通过Vue.use的方法被注入进去VUE实例中,在使用的时候我们需要全局用到vue-router的router-view和router-link组件,以及this.$router/$route这样的实例对象,那么是如何实现这些操作的呢?

经过上面的阐述,相信您已经对前端路由以及vue-router有了一些大致的了解。那么这里我们为了贯彻无解肥,我们来手把手撸一个下面这样的数据驱动的 router:

img_3ffd6ac3608b84a232d38a12a132eb55.png

思路整理

首先是数据驱动,所以我们可以通过一个route对象来表述当前路由状态,比如:

img_e08abad1c5fa49c77ac158eae156dd53.png

current.route内存放当前路由的配置信息,所以我们只要监听current.route的变化来动态render页面即可。

接着我们需要监听不同的路由变化,做相应的处理,以及实现hash和history模式。

数据驱动

这里我们延用vue数据驱动模型,实现一个简单的数据劫持,并更新视图,首先定义我们的observer

img_875baa7cb13650f71ab4baa2eae695ed.png

再接着,我们需要定义Dep和Watcher:

img_55ed235bf2a80ccee4c3f787acfbf3d4.png

到这里我们实现了一个简单的订阅-发布器,所以我们需要对current.route做数据劫持。一旦current.route更新,我们可以及时的更新当前页面:

img_79cfe6ed3e200de78ac0880995bce14c.png

恩....到这里,我们似乎已经完成了一个简单的响应式数据更新。其实render也就是动态的为页面指定区域渲染对应内容,这里只做一个简化版的render:

img_3947b6fc25fff20f5f264a688b043577.png

hash和histpry模式

接下来时hash和history模式的实现,这里我们可以沿用vue-router的思想,建立不同的处理模型便可。

img_80dad2634f3eade7e42fea728d71c615.png

当页面变化的时候,我们只需要监听hashchange和popstate事件,做路由转化transitionTo

img_d9bd7ae4d4a5b306e01501fdb7915a04.png

这样我们一方面通过this.current.route = targetRoute达到了对之前劫持数据的更新,来达到视图更新。另一方面我们又通过任务队列的调度,实现了基本的钩子函数beforeEach、beforeLeave、beforeEnter、afterEnter。

到这里其实也就差不多了,接下来我们顺带着实现几个API吧:

img_97ce1e3f6cbd0a60f6803a5ac30e9b48.png

到这里也就基本上结束了。源码地址:

https://github.com/muwoo/blogs/tree/master/src/router

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
vue+vue-route实现面包屑
vue+vue-route实现面包屑
0 0
精通Vue.js系列 │ 组件的递归
在一个组件的模板中,还可以嵌套自身组件,这样就构成了组件的递归。为了避免无限递归,需要设置递归的结束条件。
0 0
Vue.js组件中的slot 内容分发详解
Vue.js组件中的slot 内容分发详解
0 0
精通Vue.js系列 │ 注册全局组件和局部组件
普通Vue组件按照使用范围,可以以下分为两种: (1)全局组件:通过Vue应用实例的component()方法注册,可以直接被其他Vue组件访问。 (2)局部组件:只有父组件通过components选项注册了一个局部组件,父组件才能访问该局部组件。 无论是全局组件还是局部组件,都具有data、methods、computed和watch等选项,而且和根组件一样,也具有类似的生命周期及生命钩子函数。
0 0
Vue.js中的组件通信
Vue.js中的组件通信
0 0
Vue.js中的组件通信
Vue.js中的组件通信
0 0
精通Vue.js系列实例教程 │ Vue组件的单向数据流
为了简化组件的数据传递过程,避免因为在某个组件中随意修改数据而出现混乱,Vue框架提供了以下建议: (1)单向传递组件的属性,即由父组件把属性值传递给子组件的属性。 (2)在子组件中不随意修改由父组件传入的对象或数组类型的属性的内容。
0 0
精通Vue.js系列 │ Vue组件的命名规则
每个Vue组件都有一个名字。组件的名字可以采用lower-kebab-case(小写且短横隔开)或者upper-camel-case(大写且驼峰式)命名规则。
0 0
精通Vue.js系列实例教程 │ Vue组件的数据监听
如果Vue组件的一个变量num会被频繁更新,并且当变量num每次被更新时,需要进行一系列耗时的操作,如访问远程服务器的资源,或者通过复杂耗时的运算更新那些依赖变量num的其他变量(如result变量)。在这种情况下,可以通过Vue框架的数据监听器Watcher实现对变量num的监听。
0 0
+关注
廊桥梦醉
对我来说,博客首先是一种知识管理工具,其次才是传播工具。我的技术文章,主要用来整理我还不懂的知识。我只写那些我还没有完全掌握的东西,那些我精通的东西,往往没有动力写。炫耀从来不是我的动机,好奇才是。
文章
问答
文章排行榜
最热
最新
相关电子书
更多
利用编译将 Vue 组件转成 React 组件
立即下载
React Native项目实战优化之路
立即下载
基于VUE的单页面性能优化实践
立即下载