第三十一节:Vue路由:前端路由vs后端路由的了解

1. 认识前端路由和后端路由

前端路由相对于后端路由而言的, 在理解前端路由之前先对于路由有一个基本的了解

路由: 简而言之,就是把信息从原地址传输到目的地的活动

对于我们来说路由就是: 根据不同的url地址展示不同的页面内容


1.1 后端路由

以前咱们接触比较多的后端路由,当改变url地址时,浏览器会向服务器发送请求,服务器根据这个url,返回不同的资源内容

后端路由的特点就是

  1. 前端每次跳转到不同url地址,都会重新访问服务器,
  2. 服务器根据前端的路由,返回不同的数据,或者是HTML页面


1.2 前端路由

前端路由是指通过一定的技术手段,在跳转路由时不在向服务器发送请求, 而在在浏览器端进行处理,

通过不同的url映射到页面不同的DOM元素,不同的url显示不同的页面内容

也就是说

  1. 后端路由是url地址映射到服务器上的某些资源

  2. 前端路由是url地址映射到浏览器上的某些资源


1.3 什么时候使用到前端路由?

在我们开发单页面应用的时候,会常使用到前端路由

那么什么是单页面应用?

单页面应用的说明

  1. 以前后端路由不同的url地址会返回不同的HTML页面,也就是说整个项目不止一个HTML页面
  2. 单页面是指整个项目只有一个页面, 页面显示的内容被抽离为一个一个小的组件
  3. 通过前端路由,让url地址的改变来映射到不同的组件, 通过url的改变来决定组件的显示与否


1.4 单页面开发的优缺点

优点: 用户体验好

说明

  1. 单页面只有一个页面,在第一次加载时,就已经将所有资源从服务下载
  2. 在通过前端路由切换页面时,不是像服务器发送的请求,我们只是通过url决定哪些资源显示
  3. 因为不用向服务器发送请求,所以请求/响应造成的等待时间就会大大减少,提高了响应速度.

缺点:

  1. 不利于SEO优化(单页面应用,只有一个页面会被百度收录,其他的页面都是虚拟的)

  2. 使用浏览器的前进后退键的时候会重新发请求,没有合理的利用缓存

  3. 单页面无法记住之前滚动条的位置,无法在前进,后退的时候记住滚动的位置


2. 认识前端渲染和后端渲染

在理解前端渲染和后端渲染之前,先理解什么是渲染,渲染什么.

渲染就是将数据和HTML模板组合成为一个完整的能让浏览器显示说有信息内容的页面


2.1 后端渲染

后端渲染也常被称作为服务端的渲染


服务的渲染的说明:

  1. 当用户发送一个url请求是,服务器会根据路由获取对应的模板和数据,
  2. 然后服务器会将数据和模板组合成为一个完整的html页面发送给前端
  3. 浏览器获取的是一个完整的HTML页面,这就是服务的渲染


服务端渲染的好处:

  1. 前端资源消耗少, 所有的数据和模板组合是在后端完成的,因此不占用客户端的运算资源(模板解析)
  2. 首屏加载时间快,因为浏览器获取的就是一个完整的页面,因此获取后浏览器直接可以渲染视图
  3. SEO优化好, 因为SEO蜘蛛在获取页面内容的时候是一个完整的页面内容,可以更好的分析页面内容


服务端渲染的坏处:

  1. 占用太多服务器 资源


2.2 前端渲染

前端渲染也常被称为客户端渲染


前端渲染说明:

  1. 前端渲染是指浏览器将页面模板和数据进行组合形成最终的HTML页面
  2. 原理就是浏览器通过url获取服务器页面模板,服务器并不需要消化太多资源,直接将页面模板发送给前端
  3. 浏览器拿到页面也后,在解析页面是,通过页面中的ajax向后端请求数据
  4. 服务器根据前端对于数据的请求,返回给前端数据
  5. 浏览器拿到数据以后在和页面模板整合,形成最终的页面.


前端渲染的好处:

  1. 网络传输数据量小,因为一个完整的页面是通过两次请求获取的
  2. 模板在前端,因此可以通过请求不同的数据改变页面显示结果,
  3. 进而减少后端渲染时,每次请求都会返回模板解析后的结果
  4. 不占用服务器资源


前端渲染的坏处:

  1. 前端资源消耗较多,因为模板的解析和数据的处理都是需要前端处理
  2. 对于SEO优化不是特别的友好, 因为搜索引擎蜘蛛获取的是页面模板,没法分析页面全部内容


3. 前端路由实现的技术

现在对于前端路由的原理有了一定的了解,那么通过什么技术才能达到,在改变url地址是,浏览器不会向服务发送请求呢?

3.1 基于hash实现的前端路由

其实在学习HTML,CSS阶段,就已经接触并使用hash来处理页面锚点链接.

因此通过hash的改变,url不会向服务器发送请求,这就是用来前端路由的一种技术手段


hash的说明:

  1. hash就是完整的url地址#后面的内容
  2. Web 服务不会解析 hash,因为hash 仅仅是客户端的一个状态
  3. 反而前端就可以在JavaScript中通过window.location.hash来读取到
  4. 前端在读取到hash以后,就可以通过hash所代表的不同路径处理页面不同的显示逻辑


hash的特点

  1. hash 能兼容低版本的浏览器
  2. hash值的改变,不会向服务器发送请求,hash改变的值,只会在浏览器的访问历史中增加记录
  3. 因此可以通过浏览器的前进,后推按钮切换hash


hash演示示例:

因为每一次hash值发生变化都会触发window.onhashchange事件,因此可以利用hash处理前端路由

示例:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            *{
                padding: 0;
                margin:0;
            }
            li{
                list-style:none;
            }
            ul{
                display: flex;
                position: fixed;
                bottom: 0;
                left: 0;
                right:0;
                height:60px;
                border-top:1px solid #999;
            }
            li{
                flex:1;
                background: #eee;
                border-right:1px solid #999;
            }
            a{
                display:block;
                line-height:60px;
                text-align: center;
                font-size:20px;
                text-decoration: none;
            }

            .content{
                position: fixed;
                top:0;
                left:0;
                right:0;
                bottom:61px;
                background: skyblue;
                color:#fff;
                text-align:center;
                font-size:40px;
                line-height: 80px;
            }
            .box{
                display:none;
            }
            .show{
                display:block;
            }
        </style>
    </head>
    <body>
        <ul>
            <li>
                <a href="#/">首页</a>
            </li>
            <li>
                <a href="#/list">列表</a>
            </li>
            <li>
                <a href="#/about">关于作者</a>
            </li>
        </ul>
        <div class="content">
            <div id="home" class="show">首页</div>
            <div id="list" class="box">列表页</div>
            <div id="about" class="box">关于作者</div>
        </div>
        <script>

            window.onhashchange = function(){

                let path = window.location.hash.slice(1)
                // console.log(path );

                switch(path){
                    case "/":
                        home.className = "show";
                        list.className = "box"
                        about.className = "box"
                        break;
                    case "/list":
                        home.className = "box";
                        list.className = "show"
                        about.className = "box"
                        break;
                    case "/about":
                        home.className = "box";
                        list.className = "box"
                        about.className = "show"
                        break;
                }
            }
        </script>
    </body>
</html>

示例过于简单,请不要在意,重点关注,利用hash,咱们实现了路由的跳转,但是页面没有任何刷新.

这就是前端路由的精髓

hash实现前端路由原理_图1.gif


3.2 基于HTML新增的history API实现前端路由

HTML新增了history API,来操作路浏览器的历史,因为浏览器窗口会提供一个history对象,用来保存用户操作的历史,


history说明:

  1. 因为浏览器窗口提供了history来保存历史操作的url,
  2. 因此使用前进后退按键时,url地址会发生变化,但不会向服务器发送请求
  3. 但是history里保存的历史记录都是你访问过的路由,
  4. 那么我们只需要通过一定的API,将一些url路由添加到history历史记录中就可以实现不发送请求的路由跳转
  5. 因此需要借助于操作history的API


history API

  1. history.pushState: 向history对象中添加一条历史记录
  2. history.replaceState: 替换掉当前的history记录
  3. 两个方法都接受三个参数, 分别为state, title, url


pushState和replaceState 参数

  1. state用来存放将要插入的history实体的相关信息,它是一个json格式的参数;
  2. title就是传入history实体的标题
  3. url用来传递新的history实体的相对路径

history提供的这两个方法不会主动触发浏览器页面的刷新,只是history对象包括地址栏的内容会发生改变,当出发前进后退等history事件时才会进行相应的响应。


history 实现前端路由示例:

代码

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            *{
                padding: 0;
                margin:0;
            }
            li{
                list-style:none;
            }
            ul{
                display: flex;
                position: fixed;
                bottom: 0;
                left: 0;
                right:0;
                height:60px;
                border-top:1px solid #999;
            }
            li{
                flex:1;
                background: #eee;
                border-right:1px solid #999;
            }
            a{
                display:block;
                line-height:60px;
                text-align: center;
                font-size:20px;
                text-decoration: none;
            }

            .content{
                position: fixed;
                top:0;
                left:0;
                right:0;
                bottom:61px;
                background: skyblue;
                color:#fff;
                text-align:center;
                font-size:40px;
                line-height: 80px;
            }
            .box{
                display:none;
            }
            .show{
                display:block;
            }
        </style>
    </head>
    <body>
        <ul>
            <li>
                <a id="homelink">首页</a>
            </li>
            <li>
                <a  id="listlink">列表</a>
            </li>
            <li>
                <a id="aboutlink">关于作者</a>
            </li>
        </ul>
        <div class="content">
            <div id="home" class="show">首页</div>
            <div id="list" class="box">列表页</div>
            <div id="about" class="box">关于作者</div>
        </div>
        <script>

            homelink.onclick = function(){
                history.replaceState({},"home","/home")
                home.className = "show";
                list.className = "box"
                about.className = "box"
            }

            listlink.onclick = function(){
                history.replaceState({},"list","/list")
                home.className = "box";
                list.className = "show"
                about.className = "box"
            }

            aboutlink.onclick = function(){
                history.replaceState({},"about","/about")
                home.className = "box";
                list.className = "box"
                about.className = "show"
            }

        </script>
    </body>
</html>

示例图:

history风格实现前端路由_图2.gif

同样的,我们会发现页面的路径虽然发生改变,但是浏览器并未向服务器发送请求,也没有刷新页面.



当然了,这里提及前端路由,是想让大家理解前端路由的概念和实现的技术.
Vue的路由也是基于这些技术实现的, 当然了Vue路由一定是经过封装处理的,
之后我们就要看看研究研究Vue的路由了

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