第三十一節(jié):Vue路由:前端路由vs后端路由的了解

1. 認(rèn)識前端路由和后端路由

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

路由: 簡而言之,就是把信息從原地址傳輸?shù)侥康牡氐幕顒?/p>

對于我們來說路由就是: 根據(jù)不同的url地址展示不同的頁面內(nèi)容


1.1 后端路由

以前咱們接觸比較多的后端路由,當(dāng)改變url地址時,瀏覽器會向服務(wù)器發(fā)送請求,服務(wù)器根據(jù)這個url,返回不同的資源內(nèi)容

后端路由的特點就是

  1. 前端每次跳轉(zhuǎn)到不同url地址,都會重新訪問服務(wù)器,
  2. 服務(wù)器根據(jù)前端的路由,返回不同的數(shù)據(jù),或者是HTML頁面


1.2 前端路由

前端路由是指通過一定的技術(shù)手段,在跳轉(zhuǎn)路由時不在向服務(wù)器發(fā)送請求, 而在在瀏覽器端進(jìn)行處理,

通過不同的url映射到頁面不同的DOM元素,不同的url顯示不同的頁面內(nèi)容

也就是說

  1. 后端路由是url地址映射到服務(wù)器上的某些資源

  2. 前端路由是url地址映射到瀏覽器上的某些資源


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

在我們開發(fā)單頁面應(yīng)用的時候,會常使用到前端路由

那么什么是單頁面應(yīng)用?

單頁面應(yīng)用的說明

  1. 以前后端路由不同的url地址會返回不同的HTML頁面,也就是說整個項目不止一個HTML頁面
  2. 單頁面是指整個項目只有一個頁面, 頁面顯示的內(nèi)容被抽離為一個一個小的組件
  3. 通過前端路由,讓url地址的改變來映射到不同的組件, 通過url的改變來決定組件的顯示與否


1.4 單頁面開發(fā)的優(yōu)缺點

優(yōu)點: 用戶體驗好

說明

  1. 單頁面只有一個頁面,在第一次加載時,就已經(jīng)將所有資源從服務(wù)下載
  2. 在通過前端路由切換頁面時,不是像服務(wù)器發(fā)送的請求,我們只是通過url決定哪些資源顯示
  3. 因為不用向服務(wù)器發(fā)送請求,所以請求/響應(yīng)造成的等待時間就會大大減少,提高了響應(yīng)速度.

缺點:

  1. 不利于SEO優(yōu)化(單頁面應(yīng)用,只有一個頁面會被百度收錄,其他的頁面都是虛擬的)

  2. 使用瀏覽器的前進(jìn)后退鍵的時候會重新發(fā)請求,沒有合理的利用緩存

  3. 單頁面無法記住之前滾動條的位置,無法在前進(jìn),后退的時候記住滾動的位置


2. 認(rèn)識前端渲染和后端渲染

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

渲染就是將數(shù)據(jù)和HTML模板組合成為一個完整的能讓瀏覽器顯示說有信息內(nèi)容的頁面


2.1 后端渲染

后端渲染也常被稱作為服務(wù)端的渲染


服務(wù)的渲染的說明:

  1. 當(dāng)用戶發(fā)送一個url請求是,服務(wù)器會根據(jù)路由獲取對應(yīng)的模板和數(shù)據(jù),
  2. 然后服務(wù)器會將數(shù)據(jù)和模板組合成為一個完整的html頁面發(fā)送給前端
  3. 瀏覽器獲取的是一個完整的HTML頁面,這就是服務(wù)的渲染


服務(wù)端渲染的好處:

  1. 前端資源消耗少, 所有的數(shù)據(jù)和模板組合是在后端完成的,因此不占用客戶端的運算資源(模板解析)
  2. 首屏加載時間快,因為瀏覽器獲取的就是一個完整的頁面,因此獲取后瀏覽器直接可以渲染視圖
  3. SEO優(yōu)化好, 因為SEO蜘蛛在獲取頁面內(nèi)容的時候是一個完整的頁面內(nèi)容,可以更好的分析頁面內(nèi)容


服務(wù)端渲染的壞處:

  1. 占用太多服務(wù)器 資源


2.2 前端渲染

前端渲染也常被稱為客戶端渲染


前端渲染說明:

  1. 前端渲染是指瀏覽器將頁面模板和數(shù)據(jù)進(jìn)行組合形成最終的HTML頁面
  2. 原理就是瀏覽器通過url獲取服務(wù)器頁面模板,服務(wù)器并不需要消化太多資源,直接將頁面模板發(fā)送給前端
  3. 瀏覽器拿到頁面也后,在解析頁面是,通過頁面中的ajax向后端請求數(shù)據(jù)
  4. 服務(wù)器根據(jù)前端對于數(shù)據(jù)的請求,返回給前端數(shù)據(jù)
  5. 瀏覽器拿到數(shù)據(jù)以后在和頁面模板整合,形成最終的頁面.


前端渲染的好處:

  1. 網(wǎng)絡(luò)傳輸數(shù)據(jù)量小,因為一個完整的頁面是通過兩次請求獲取的
  2. 模板在前端,因此可以通過請求不同的數(shù)據(jù)改變頁面顯示結(jié)果,
  3. 進(jìn)而減少后端渲染時,每次請求都會返回模板解析后的結(jié)果
  4. 不占用服務(wù)器資源


前端渲染的壞處:

  1. 前端資源消耗較多,因為模板的解析和數(shù)據(jù)的處理都是需要前端處理
  2. 對于SEO優(yōu)化不是特別的友好, 因為搜索引擎蜘蛛獲取的是頁面模板,沒法分析頁面全部內(nèi)容


3. 前端路由實現(xiàn)的技術(shù)

現(xiàn)在對于前端路由的原理有了一定的了解,那么通過什么技術(shù)才能達(dá)到,在改變url地址是,瀏覽器不會向服務(wù)發(fā)送請求呢?

3.1 基于hash實現(xiàn)的前端路由

其實在學(xué)習(xí)HTML,CSS階段,就已經(jīng)接觸并使用hash來處理頁面錨點鏈接.

因此通過hash的改變,url不會向服務(wù)器發(fā)送請求,這就是用來前端路由的一種技術(shù)手段


hash的說明:

  1. hash就是完整的url地址#后面的內(nèi)容
  2. Web 服務(wù)不會解析 hash,因為hash 僅僅是客戶端的一個狀態(tài)
  3. 反而前端就可以在JavaScript中通過window.location.hash來讀取到
  4. 前端在讀取到hash以后,就可以通過hash所代表的不同路徑處理頁面不同的顯示邏輯


hash的特點

  1. hash 能兼容低版本的瀏覽器
  2. hash值的改變,不會向服務(wù)器發(fā)送請求,hash改變的值,只會在瀏覽器的訪問歷史中增加記錄
  3. 因此可以通過瀏覽器的前進(jìn),后推按鈕切換hash


hash演示示例:

因為每一次hash值發(fā)生變化都會觸發(fā)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">關(guān)于作者</a>
            </li>
        </ul>
        <div class="content">
            <div id="home" class="show">首頁</div>
            <div id="list" class="box">列表頁</div>
            <div id="about" class="box">關(guān)于作者</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>

示例過于簡單,請不要在意,重點關(guān)注,利用hash,咱們實現(xiàn)了路由的跳轉(zhuǎn),但是頁面沒有任何刷新.

這就是前端路由的精髓

hash實現(xiàn)前端路由原理_圖1.gif


3.2 基于HTML新增的history API實現(xiàn)前端路由

HTML新增了history API,來操作路瀏覽器的歷史,因為瀏覽器窗口會提供一個history對象,用來保存用戶操作的歷史,


history說明:

  1. 因為瀏覽器窗口提供了history來保存歷史操作的url,
  2. 因此使用前進(jìn)后退按鍵時,url地址會發(fā)生變化,但不會向服務(wù)器發(fā)送請求
  3. 但是history里保存的歷史記錄都是你訪問過的路由,
  4. 那么我們只需要通過一定的API,將一些url路由添加到history歷史記錄中就可以實現(xiàn)不發(fā)送請求的路由跳轉(zhuǎn)
  5. 因此需要借助于操作history的API


history API

  1. history.pushState: 向history對象中添加一條歷史記錄
  2. history.replaceState: 替換掉當(dāng)前的history記錄
  3. 兩個方法都接受三個參數(shù), 分別為state, title, url


pushState和replaceState 參數(shù)

  1. state用來存放將要插入的history實體的相關(guān)信息,它是一個json格式的參數(shù);
  2. title就是傳入history實體的標(biāo)題
  3. url用來傳遞新的history實體的相對路徑

history提供的這兩個方法不會主動觸發(fā)瀏覽器頁面的刷新,只是history對象包括地址欄的內(nèi)容會發(fā)生改變,當(dāng)出發(fā)前進(jìn)后退等history事件時才會進(jìn)行相應(yīng)的響應(yīng)。


history 實現(xiàn)前端路由示例:

代碼

<!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">關(guān)于作者</a>
            </li>
        </ul>
        <div class="content">
            <div id="home" class="show">首頁</div>
            <div id="list" class="box">列表頁</div>
            <div id="about" class="box">關(guān)于作者</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風(fēng)格實現(xiàn)前端路由_圖2.gif

同樣的,我們會發(fā)現(xiàn)頁面的路徑雖然發(fā)生改變,但是瀏覽器并未向服務(wù)器發(fā)送請求,也沒有刷新頁面.



當(dāng)然了,這里提及前端路由,是想讓大家理解前端路由的概念和實現(xiàn)的技術(shù).
Vue的路由也是基于這些技術(shù)實現(xiàn)的, 當(dāng)然了Vue路由一定是經(jīng)過封裝處理的,
之后我們就要看看研究研究Vue的路由了

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容