前端路由实现方法

一、什么是前端路由

        在web开发的过程中,路由的使用是必不可少的,这里的路由不是指我们日常生活中的路由器,但是实现原理基本相同,它代表一个url与相应处理程序的影射关系,用户在输入要访问的url之后,路由会解析url中的路径,之后根据映射表中的映射关系查找相应的预设函数,并将结果返回给用户,以此完成一次操作。

       前端路由不同于传统路由,它不需要服务器来进行解析,而是通过一个hash函数或者H5提供的history API来实现。在进行开发时,路由用来设定访问路径,并将路径与相应的组件映射起来,用户在访问相应的路径时,路由根据映射关系实现不同组件间的切换,整个过程都是在同一个页面中实现,不涉及页面间的跳转,也就是我们常说的单页应用。

二、前端路由的优势

        1、页面刷新速度快。由于后端路由在请求一个新路径时,会重新向服务器发送请求,之后再根据服务器的相应结果重新渲染页面,这个过程会受到网络延迟的影响,而前端路由省略了整个请求过程,只是完成部分组件间的切换,因此页面的刷新速度会相对较快,用户体验相对较好。

        2、复用性强。使用前端路由,代码中的layout、css、js都可以共用,以此来减少重复加载,提供程序性能。

        3、页面状态可记录。不使用前端路由,仅通过ajax进行页面局部切换的单页应用,由于url始终保持不变,因此页面的状态是无法记录的,而前端路由很好的解决了这个问题。例如使用了前端路由的url:http://music.taihe.com/fe/a这个链接,再打开后会直接触发/a的事件。

三、前端路由的实现方法

        目前前端路由的实现方法主要有两种方法,location.hash和window.history。

        1、通过location.hash实现前端路由

        hash就是一个url中#后面的部分,也叫做url的锚部分,锚部分在服务器端会被自动忽略,但是在浏览器中是可以通过loaction.hash来获取的。通过hash方法实现前端路由主要是用到的是onhashchange事件,这个事件可以实时监听url中hash值的变化,由此来根据hash值的变化进行一些DOM的切换操作。

        onhashchange的语法如下:

        HTML中:

            <element onhashchange="myScript">

        Javascipt中:

            object.onhashchange=function(){myScript};

        Javascript中,使用addEventListener()方法:

            object.addEventListener("hashchange", myScript);

        onhashchange事件有如下几种触发条件:

            a)改变url地址,在最后面增加或改变其hash值;

            b)改变location.href或location.hash的值;

            c)点击带有锚点的链接;

            d)浏览器前进后退可能导致hash的变化,前提是两个网页地址中的hash值不同。

        利用Hash实现前端路由:

          设计思路:当浏览器地址栏url的hash值发生变化时,就会触发onhashchange事件,这时通过window.location.hash可以拿到当前浏览器的url的hash值,注意此时的hash值是带有#的,因此需要对其值进行相应的处理,去掉#,并且如果当前url不含hash值的话,就将其当做根目录处理。之后将url和相应的组件函数进行映射,根据不同的hash值执行不同的回调函数,也就是加载相应的组件。

        代码如下:        


这里简单写了一个DOM元素,用来模拟路由接受到url后对不同组件的切换情况



此时,点击不同a标签可以实现组件间的切换,同时,页面并没有刷新。

    2、通过window.history和popstate实现前端路由

        浏览器窗口会为用户提供一个history对象,用来保存用户操作页面的历史,我们在浏览网页时的前进后退操作都是基于这个对象来实现的。在前端路由的实现过程中主要用到了history对象里的history.pushState()和history.replaceState(),这两个接口。

                                        history.replaceState(dataObj,title,url);

                                        history.pushState(dataObj,title,url);

        pushState()和replaceState()方法很类似,二者均接受三个参数,分别是state、title和url。其中state用来存放将要插入的history实体的相关信息,它是一个json格式的参数;title就是传入history实体的标题,需要注意的是firefox现在会自动忽略掉这个参数;url用来传递新的history实体的相对路径,如果其值为null则表示当前要插入的history实体与前一个实体一致,没有改变。replaceState()方法与pushState()方法的唯一区别在于,replaceState()方法会将最新一条的history实体覆盖掉,而不是直接添加,这种情况在处理例如登录页面这些不需要记录到history中的情况时非常有用。

        这里需要注意的是history提供的这两个方法不会主动出发浏览器页面的刷新,只是history对象包括地址栏的内容会发生改变,当出发前进后退等history事件时才会进行相应的响应。另外,作为参数传入的url也会受到同源策略的限制,如果出现跨域等情况会导致报错。

        popstate是官方提供的事件,当history中的记录发生改变时就会触发该事件。

利用history实现前端路由:        

    设计思路:当想要跳转到指定url的时候,将目标url通过pushState()或者replaceState()方法填入到history和地址栏中,此时由于上述两种方法不会主动进行页面刷新,因此页面仍停留在当前页面,只是url地址发生了改变。之后通过popstate事件响应,执行相应的回调函数,实现前端组件间的切换。

    这里直接使用mozilla的例子,代码如下:




可以看到在点击相应的dom元素的时候地址栏和相应的router-view同时发生了改变。


总结: 前端路由由于其刷新速度快、用户体验好的特点在web开发中已经被广泛的使用了,许多大型的前端框架,如react、vue都有自己的前端路由,关于前端路由的学习不能仅停留在会使用上,更应该从底层原理入手学习。今后还会对vue-router、react-router等源码进行学习,从而使自己能够对前端路由有更细致深刻的了解和解读。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,647评论 18 139
  • 前端开发面试题 <a name='preface'>前言</a> 只看问题点这里 看全部问题和答案点这里 本文由我...
    自you是敏感词阅读 758评论 0 3
  • 计划已久的西行之旅今天启程。这次行程的主题是与一年前结缘助学的蓉儿见面,和她一起待上二天。带她走出县城去看看外面的...
    江南阿松阅读 394评论 0 2
  • 好久不见。 她难得上一次QQ,忘了隐身。一个曾经熟识的人发来这四个字。 只一年多的时间,算不上太久,所以记忆都很清...
    九月十六六阅读 466评论 0 1