前端世界中的路由

NO IMAGE

前言

在前端架構中,路由的設計的合理與否決定了這個項目的是否優秀。現在前端的框架angular,vue react都有對應的路由插件,在頁面渲染方便基本都不用我們前端工程師考慮,基本上我們安裝他們的文檔配置好路由都能良好的運行,但是這並不意味我們不需要去掌握路由的實現原理。

發展

初始的web路由(後端控制)

  • 後臺控制路由渲染
  • 頁面跳轉會重新渲染整個頁面
  • 瀏覽可以自動記錄頁面路由跳轉歷史
  • 所有內容需要瀏覽器向服務器發出請求
  • 服務器端返回對應路由的信息
  • 需要瀏覽器再次解析返回信息
var express = require('express');
var path = require('path');
var app = express();
// 設置模版渲染引擎路徑
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
//nodejs根據路由渲染
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/index', function(req, res, next) {
res.render('index', { title: 'I am index.' });
});
/* GET home page. */
router.get('/admin', function(req, res, next) {
res.render('admin', { title: 'I am admin.' });
});
module.exports = router;

總結:簡單來說路由就是用來跟後端服務器進行交互的一種方式,通過不同的路徑,來請求不同的資源,請求不同的頁面是路由的其中一種功能。

單頁面路由機制(前端完全控制)

  • 靜態文件只需要請求一次
  • 路由跳轉頁面只需要部分刷新
  • 前端完全設計路由
  • 只有動態數據與後臺進行ajax交互
  • 實現方式:hash和history

對比

後臺控制單頁面路由機制
加載速度加載所有數據,重新渲染dom部分dom渲染以及部分數據
切換效果重新刷新中間白屏平滑過渡
動態數據交互ajax交互ajax交互
維護成本前後端溝通只需要前端控制

從對比中我們可以發現,單頁面路由機制無論在維護成本,渲染速度以及用戶體驗度上都是完勝後臺控制設計的路由。這也是目前除了一些老項目還採用後臺控制路由的方式其他基本都是採用單頁面路由機制渲染的原因。

注:現在的ssr渲染本質上也是屬於單頁面路由設計,ssr只是採用了後臺進行首屏渲染,路由的實際控制權還是在前端的。

單頁面路由實現方式

hash實現方式

  • 介紹:還記得剛開始工作時做過公司的官網,那個時候tab的跳轉就是直接加載另一個html,但這樣會在第一次切換是如果頁面資源過大會導致白屏。後來搜索了下解決方案就是所有的tab內容放到一個頁面裡每個部分加上不同的hash然後點擊tab通過hash來顯示相應的html。我想這應該是最初的單頁面路由實現方式的。
  • 實現方式:利用dom的事件hashchange(當URL的片段標識符更改時,將觸發hashchange事件 (跟在#符號後面的URL部分,包括#符號))來監聽路由上hash的邊從而渲染對應的頁面。
// 監聽hash變化
window.addEventListener('hashchange', function(event){ 
console.log('===current hash===')
console.log(window.location.hash)
console.log('new url====='+ event.newURL); // hash 改變後的新 url
console.log('old url====='+ event.oldURL)// hash 改變前的舊 url
},false)
//或者此種寫法
window.onhashchange = funcRef;
function funcRef(event){
......
}
let hash = window.location.hash; // 獲取當前 hash 值
//在html中可以加入一下代碼測試
<div>
<a href="#/hash1">hash1</a>
<a href="#/hash2">hash2</a>
<a href="#/hash3">hash3</a>
</div>

注:回調函數中的參數說明請查看文檔

  • 總結:hash路由可以較好的實現頁面的交互,並且對於瀏覽器有良好的兼容性,但是唯一不足的是他的設計美觀上,hash路由中必須帶個#,這對於我們線上項目來說是非常不美觀的,隨著html5的api發展hash在前端路由中必將會被慢慢的取代。

h5的history實現

  • 介紹:在 HTML5 出現之前,瀏覽器就已經有了 history 對象。但在早期的 history 中只能用於多頁面的跳轉有以下的api:
history.go(num);// num 正數為前進num頁 負數為後退num頁
history.forward();// 前進一頁
history.back(); //後退一頁

在html5的api中history新增了可以控制路由的幾個api:

//param1:狀態對象 title:標題(保留字段)   url:路由url
history.pushState(stateObj,title,url)
history.replaceState(stateObj,title,url)  // 替換當前路由狀態
history.state   // 獲取history中的狀態對象

注:詳細文檔請查看mdn文檔

  • 實現方式:
待研究過react-router和vue-route源碼後再來補上

對比

hash模式的優點:

    1. 兼容性更好
    1. 無需服務器處理非單頁應用中的路由
    1. 當前頁面刷新不會404(history需要服務器配置)

history 模式的優點:

    1. 路由設計更優雅(沒有#)。
    1. 頁面中可以繼續使用錨點功能
    1. 相同的路由仍然可以放到歷史棧中。

注:就個人而言覺得history是前端路由的發展方向

參考

「前端進階」徹底弄懂前端路由

總結

自工作以來已有四年多了,接觸前端這塊應該有五年多了,隨著學的東西越多約會發現自己對於知識的匱乏,時而焦慮自己笨拙,時而害怕會被時代拋棄,但隨著年齡漸漸的增長,生活漸漸的穩定,心態也慢慢平緩,只要你夠努力生活必然不會負你。廢話不多說了,最後送諸君一句:書山有路勤為徑,學海無涯苦作舟。諸君共勉。

相關文章

學習element源碼實現自己的表單控件

Spring自定義標籤的實現

2019年年終總結

雲原生安全更安全的密文管理VaultonACK