摘要:在單頁應(yīng)用開發(fā)中,并不是必須的,所以今天只講講前端的路由系統(tǒng)以及的簡單使用。當(dāng)頁面狀態(tài)發(fā)生變化時,相應(yīng)變化,重新加載時又可以通過中攜帶的直接將頁面設(shè)置到對應(yīng)的狀態(tài)。此時可以使用來設(shè)置一個默認(rèn)頁面。
最近業(yè)余時間在學(xué)習(xí) React,配合 Redux 和 React-Router 正在不緊不慢地開發(fā)一個小工具moviemaster,用于管理硬盤中的電影劇集。在單頁應(yīng)用開發(fā)中,redux 并不是必須的,所以今天只講講 前端的路由系統(tǒng)以及 React-Router的簡單使用。
什么是路由以下來自維基百科::
路由(routing)就是通過互聯(lián)的網(wǎng)絡(luò)把信息從源地址傳輸?shù)侥康牡刂返幕顒印B酚砂l(fā)生在OSI網(wǎng)絡(luò)參考模型中的第三層即網(wǎng)路層。
路由引導(dǎo)分組轉(zhuǎn)送,經(jīng)過一些中間的節(jié)點后,到它們最后的目的地。
這是網(wǎng)絡(luò)工程中的術(shù)語,對大家而言,最熟悉的應(yīng)該就是家里的路由器。路由是指路由器從一個接口上收到數(shù)據(jù)包,根據(jù)數(shù)據(jù)包的目的地址進(jìn)行定向并轉(zhuǎn)發(fā)到另一個接口的過程。放在 Web 上來說,url 就像是路由器中的路由表,每個 url 對應(yīng)不同的頁面或者內(nèi)容,就像路由表中的的 IP 對應(yīng)不同的網(wǎng)絡(luò)一樣。
先來看一下熟悉的套路:
在傳統(tǒng)的網(wǎng)頁應(yīng)用架構(gòu)中,客戶端只是一個展示層,通過 url 訪問服務(wù)端,服務(wù)端則根據(jù)自己的“路由表”將對應(yīng)的頁面分發(fā)給客戶端。但是在這種模式下,ajax 異步加載的內(nèi)容是無法通過url 記錄的。無論你在頁面上操作了多少,異步請求了多少數(shù)據(jù),在每次重新訪問同一個 url 時,服務(wù)端返回給客戶端的內(nèi)容都是一模一樣。
如果前端有自己專屬的“路由表”來分發(fā)頁面上不同的狀態(tài),那不就行了?
Hash 和 pushState據(jù)我所知,目前有兩種方式可以構(gòu)建出前端的路由系統(tǒng):url 中的#和 HTML5中的 history API。其原理如下:
阻止標(biāo)簽的默認(rèn)跳轉(zhuǎn)動作。
ajax或者 Fetch 請求內(nèi)容。
將返回的內(nèi)容添加到頁面中。
使用 hash 或者 pushState 修改 url。
經(jīng)典的 Hash#代表網(wǎng)頁中的一個位置。后面接著的字符,就是該位置的標(biāo)識符。比如,
https://zhanglun.github.io/index.html#body
就代表網(wǎng)頁 index.html 的 body 位置。瀏覽器讀取這個 URL 后,會自動將body位置滾動至可視區(qū)域。標(biāo)識符的指定有兩個方法。
使用錨點
使用id屬性
#是用來指向文檔的內(nèi)容,屬于瀏覽器的行為,與服務(wù)端無關(guān),在 HTTP請求中也不會攜帶 #及其后面的內(nèi)容,對于服務(wù)端而言 http://www.baidu.com 和 http://www.baidu.com#action=fuckbaidu 返回給客戶端的都是前者所分發(fā)的內(nèi)容,但是在瀏覽器中可以通過 Window 對象上的 location.hash 進(jìn)行操作。因此,在瀏覽器中可以通過 hash 來記錄頁面的狀態(tài),構(gòu)建“路由表”。當(dāng)頁面狀態(tài)發(fā)生變化時,hash 相應(yīng)變化,重新加載時又可以通過 url 中攜帶的 hash 直接將頁面設(shè)置到對應(yīng)的狀態(tài)。
比如:
http://www.example.com/ http://www.examplt.com/#edit http://www.examplt.com/#settings訪問/時,呈現(xiàn)主頁。
點擊頁面上的Edit按鈕,頁面呈現(xiàn)編輯對應(yīng)的內(nèi)容。通過 url 直接訪問時,檢查 hash 是否和 edit 匹配,如果匹配執(zhí)行加載編輯內(nèi)容的代碼
點擊頁面上的Settings按鈕,頁面呈現(xiàn)設(shè)置對應(yīng)的內(nèi)容。通過 url 直接訪問時,檢查 hash 是否和 settings 匹配,如果匹配執(zhí)行加載編輯內(nèi)容的代碼。
以下是偽代碼:
function hashHandler () { let key = location.hash.slice(1); switch(key) { case "edit": renderEditPanel(); break; case "settings": renderSettings(); break; default: break; } } window.onload = () => { hashHandler(); } window.onhashchange = () => { hashHandler(); }HTML5 中的 pushStatepushState是 History API中的一個方法,其文檔可以看這里 MDN History。它的功能簡單的說就是:修改 url,添加歷史記錄。比如/blogs和settings對應(yīng)的是兩個頁面,如果只是在頁面上點擊標(biāo)簽切換,需要做的操作只有:發(fā)送請求修改頁面內(nèi)容和調(diào)用 pushState 方法修改 url。問題來了,對于前端而言需要將其視為同一個頁面,但實際上這兩個 url 對于服務(wù)端來說是兩個不同的請求,所以這里需要服務(wù)端的配合。
我的做法是:對應(yīng)的url 返回的都是同一個頁面,然后瀏覽器接受之后檢查前端定義路由系統(tǒng),執(zhí)行響應(yīng)的代碼。這個方法可能會造成頁面平白添加一個短暫的延遲,不過影響不是很大。
React-Router的使用目前來說,任何一個路由系統(tǒng)庫或者框架,雖說是寫法不一,但是都是在上述兩種方式的基礎(chǔ)上實現(xiàn)的。讓我覺得耳目一新的是:使用路由嵌套的概念來定義 view 的嵌套集合,當(dāng)一個給定的 URL 被調(diào)用時,整個集合中(命中的部分)都會被渲染。
import React from "react"; import { render } from "react-dom"; import { Router, Route, IndexRoute, hashHistory } from "react-router"; import App from "./containers/App"; import MovieContainer from "./containers/Movies"; import Detail from "./containers/Detail"; let rootElement = document.getElementById("app"); render(, rootElement); 在入口文件中,引入 React-Router,以組件的形式在 render 中使用,上述代碼配置結(jié)果如下:
URL 組件 / App /about App -> About /inbox App -> Inbox /inbox/messages/:id App -> Inbox -> Message 在路由中,組件對應(yīng)設(shè)置的子組件可以通過 this.props.children 渲染在父組件中
class App extend Component { constructor(props) { super(props) } render() {} }Hello, world!
{this.props.children}當(dāng) URL 為 / 時, App 中并沒有渲染任何的組件,render 中的 this.props.children 還是 undefined。此時可以使用 IndexRoute 來設(shè)置一個默認(rèn)頁面。
render(, rootElement); {/* 當(dāng) url 為/時渲染 Welcome */}
URL 組件 / App -> Welcome /about App -> About /inbox App -> Inbox /inbox/messages/:id App -> Inbox -> Message 看一下這一段代碼
此時匹配的路由分別是:/posts,/posts/usres/:userid 和/posts/users/:userid/messages/:messageid,可以看出,嵌套的
所匹配的 url是包裹著它的 的 path “之和”。但是問題又來了,嵌套的好處在于路由之間結(jié)構(gòu)清晰直觀,但是也會導(dǎo)致 url 的不美觀,試想/posts/users/:userid/messages/:messageid這么長的路由也是著實讓人心累。React-Router 的配置提供了一個選擇:將 Route 的 path 設(shè)置成絕對路徑。同時可以使用 將修改為絕對路徑的路由重定向到之前的設(shè)置
URL 組件 /posts App -> Post /user/:userid App -> Post -> User /messages/:messageid App -> Post -> User ->Message 基礎(chǔ)的配置完成之后,通過 自動或者通過browserHistory和hashHistory手動執(zhí)行路由的跳轉(zhuǎn)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/80713.html
摘要:是一個基于和的服務(wù)器端和瀏覽器端的的前后端全棧應(yīng)用框架。是的組件,并且會進(jìn)行數(shù)據(jù)初始化不但可以支持的數(shù)據(jù)初始化,還可以合并和的,使用同一個,和的無縫結(jié)合。 koa-cola是一個基于koa和react的服務(wù)器端SSR(server side render)和瀏覽器端的SPA(single page application)的web前后端全棧應(yīng)用框架。 koa-cola使用typescr...
摘要:項目技術(shù)棧項目地址項目演示現(xiàn)在比較流行的腳手架應(yīng)該是,由官方開發(fā)。網(wǎng)上關(guān)于項目的目錄結(jié)構(gòu)也很多,那應(yīng)該怎么合理地去組織我們的目錄結(jié)構(gòu)呢為了處理這個問題,我參考了一些項目,然后把它們的優(yōu)點結(jié)合起來,最后寫了這個腳手架。 項目技術(shù)棧:react16+react-router4+antd-mobile2+mobx+axios+webpack4項目github地址:https://github...
摘要:但是使用標(biāo)記將告訴瀏覽器處理路由就像服務(wù)器端路由一樣。組件需要一個稱為的屬性指向要渲染的客戶端路由。發(fā)生這種情況的原因是響應(yīng)路由器將渲染與路徑匹配的所有內(nèi)容除非另有指定。屬性預(yù)計將是一個函數(shù)將在對象連同和路由配置時調(diào)用。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3815原文:https://www.fullstackrea...
摘要:一為什么選擇是當(dāng)前前端應(yīng)用最廣泛的框架。目前來看的生態(tài)系統(tǒng)要比大的多,在等最大的技術(shù)社區(qū)搜索兩者,的搜索結(jié)果是的十倍左右,另外據(jù)近期統(tǒng)計使用的站點是的幾百倍以上。其中是基于技術(shù),依然是瀏覽器應(yīng)用。 一、為什么選擇React React是當(dāng)前前端應(yīng)用最廣泛的框架。三大SPA框架 Angular、React、Vue比較。 Angular出現(xiàn)最早,但其在原理上并沒有React創(chuàng)新的性能優(yōu)化...
摘要:項目地址基于構(gòu)建的移動端單頁微應(yīng)用,適合于核心概念的理解與掌握。前言這個項目是介于版本之后并且完全仿照功能設(shè)計的版本。但隨之而來通常會有這樣的疑問概念太多,并且都是分離的分文件。 react-mobile-starter 項目地址 基于 react + redux + react-router 構(gòu)建的移動端單頁微應(yīng)用,適合于react、redux、react-router核心概念的理解...
閱讀 3420·2021-11-24 09:38
閱讀 3196·2021-11-22 09:34
閱讀 2112·2021-09-22 16:03
閱讀 2373·2019-08-29 18:37
閱讀 383·2019-08-29 16:15
閱讀 1774·2019-08-26 13:56
閱讀 867·2019-08-26 12:21
閱讀 2208·2019-08-26 12:15