美文网首页
浅谈前端路由

浅谈前端路由

作者: Srtian | 来源:发表于2018-09-28 21:41 被阅读332次

    关于秋招的一些感想

    最近一段时间忙着秋招,一路经历了阿里终面挂,美团终面挂等等,感觉自己有点苦逼(尤其是因为没HC而挂是最难受的)。虽然到现在还没得到满意的结果,但这个过程还是有所收获的,这是虽然一个自我怀疑的过程,但也是一个不断弥补自身不足,学习的过程,其中与一些面试我的师兄在交流的过程中也是受益匪浅,并且也对自身以后要走的路有了一个更加明确的认识,所以前途漫漫还需努力呀!

    一、路由

    在现代前端开发中,路由是非常重要的一环。但路由到底是什么呢?有些说:路由就是指随着浏览器地址栏的变化,展示给用户的页面也不相同。这是从路由的用途上来解释路由是什么的,还有一种说法是:路由就是URL到函数的映射。这是从路由的实现原理上来解释路由是什么的。这两种说法都很有道理,但我个人认为还是第二种比较切合我自己对路由的理解吧。

    上面已经说了上面是路由,而路由本身也经历了不同的发展阶段:

    1. 后端路由
    2. 前端路由

    后端路由又可称之为服务器端路由,因为对于服务器来说,当接收到客户端发来的HTTP请求,就会根据所请求的相应URL,来找到相应的映射函数,然后执行该函数,并将函数的返回值发送给客户端。对于最简单的静态资源服务器,可以认为,所有URL的映射函数就是一个文件读取操作。对于动态资源,映射函数可能是一个数据库读取操作,也可能是进行一些数据的处理,等等。然后根据这些读取的数据,在服务器端就使用相应的模板来对页面进行渲染后,再返回渲染完毕的页面。这种方式在早期的前端开发中非常普遍,它的好处与坏处都很明显:

    • 好处:安全性好,SEO好。
    • 缺点:加大服务器的压力,不利于用户体验,代码冗合。

    也正是由于后端路由还存在着自己的不足,前端路由才有了属于自己的一片天地与发展的空间。对于前端路由来说,路由的映射函数通常是进行一些DOM的显示和隐藏操作。这样,当访问不同的路径的时候,会显示不同的页面组件。前端路由主要有以下两种实现方案:

    • hash
    • history API

    当然,前端路由也存在缺陷:使用浏览器的前进,后退键时会重新发送请求,来获取数据,没有合理地利用缓存。但总的来说,现在前端路由已经是实现路由的主要方式了,我们常用的诸如react-router等前端框架的路由控制都是基于前端路由进行开发的,因此将前端路由进行一个了解
    还是很有必要的。

    二、前端路由的实现

    2.1 基于hash

    早期的前端路由的实现就是基于location.hash来实现的。其实现原理也很简单,location.hash的值就是URL中#后面的内容。比如下面这个网站,它的location.hash='#me':

    https://www.srtian.com#me

    此外,hash也存在下面几个特性:

    • URL中hash值只是客户端的一种状态,也就是说当向服务器端发出请求时,hash部分不会被发送。
    • hash值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制hash的切换。
    • 我们可以使用hashchange事件来监听hash的变化。

    出发hsah变化的方式也有两种,一种是通过a标签,并设置href属性,当用户点击这个标签后,URL就会发生改变,也就会触发hashchange事件了:

    <a href="#srtian">srtian</a>
    

    还有一种方式就是直接使用JavaScript来对loaction.hash进行赋值,从而改变URL,触发hashchange事件:

    location.hash="#srtian"
    

    2.2 基于History API

    前面的hash虽然也很不错,但使用时都需要加上#,并不是很美观。因此到了HTML5,又提供了History API来实现URL的变化。其中做最主要的API有以下两个:history.pushState()和history.repalceState()。

    这两个API可以在不进行刷新的情况下,操作浏览器的历史纪录。唯一不同的是,前者是新增一个历史记录,后者是直接替换当前的历史记录。此外,这两个api都接受三个参数:

    window.history.pushState(null, null, "http://www.163.com");
    
    • 状态对象(state object):一个JavaScript对象,与用pushState()方法创建的新历史记录条目关联。无论何时用户导航到新创建的状态,会触发popstate事件,并能在事件中使用该对象。
    • 标题(title):一般浏览器会忽略,最好传入null。
    • 地址(URL):就是需要新增的历史记录的地址,浏览器不会去直接加载改地址,但后面也可能会去尝试加载该地址。此外需要注意的是,传入的URL与当前URL应该是同源的。

    这一块的详情可以去看MDN,它做了一个比较详细的介绍:

    https://developer.mozilla.org/en-US/docs/Web/API/History

    此外,还提供了popstate事件来监听历史记录的变化。

    可以看看下面这个实例:

    <p id="example">
     <a href="/name" title="name">name</a>
     <a href="/age" title="age">age</a>?
    </p>
    <div class="main" id="main"></div>
    <script>
    ;(function(){
        var examplebox = document.getElementById('example')
        var mainbox = document.getElementById('main')
        
        examplebox.addEventListener('click', function(e){
            e.preventDefault()
            var elm = e.target
            var uri = elm.href
            var tlt = elm.title
            history.pushState({path:uri,title:tlt}, null, uri)
            mainbox.innerHTML = 'current page is '+tlt
        })
        window.addEventListener('popstate',function(e){
            var state = e.state
            mainbox.innerHTML = 'current page is ' + state.title
        })
    })()
    </script>
    

    两种实现方式的对比:基于Hash的路由实现,兼容性更好;而基于History API的路由,则更正式,更美观,可以设置与当前URL同源的任意URL,路径更直观。此外,基于Hash的路由不需要对服务器做改动,基于History API的路由需要对服务器做一些改造,需要对不同的路由进行相应的设置才行。

    三、React-Router

    由于我现在也就对React-Router比较熟悉,Vue学了太久了,忘记了。Angular刚学,还没到路由这块这来,因此就以React-Router为例,来聊聊现代前端框架的路由实现思路。先来看看一个简单的React中的Router代码:

    <Router>
        <Switch>
            <Route path="/about" component={About}/> 
            <Route path="/:user" component={User}/> 
        </Switch> 
    </Router>
    

    其实现思路也很简单如下图所示:


    image

    其实现思路很简单:About和User这两个component一直都存在。当路由发生改变时,与URL相匹配的component机会被成功渲染。而不匹配的component就设置为null。

    具体实现,大家可以看这篇文章,这位大佬做了很详细的介绍:

    https://github.com/youngwind/blog/issues/109

    参考资料:

    https://github.com/youngwind/blog/issues/109

    https://zhuanlan.zhihu.com/p/24814675

    https://segmentfault.com/a/1190000007238999

    http://www.cnblogs.com/yuqing6/p/6731980.html

    相关文章

      网友评论

          本文标题:浅谈前端路由

          本文链接:https://www.haomeiwen.com/subject/zujmoftx.html