
大家好,我是小丞同學,一名大二的前端愛好者
這篇文章是學習 React 中 React 路由的學習筆記
非常感謝你的閱讀,不對的地方歡迎指正
願你忠于自己,熱愛生活
引言
在我們之前寫的頁面當中,用我們的慣用思維去思考的話,可能會需要寫很多的頁面,例如做一個 tab 欄,我們可能會想每個選項都要對應一個 HTML 檔案,這樣會很麻煩,甚至不友好,我們把這種稱為 MPA 也叫多頁面應用。
1. SPA
而為了減少這樣的情況,我們還有另一種應用,叫做 SPA ,單頁應用程式
它比傳統的 Web 應用程式更快,因為它們在 Web 浏覽器本身而不是在伺服器上執行邏輯。在初始頁面加載後,隻有資料來回發送,而不是整個 HTML,這會降低帶寬。它們可以獨立請求标記和資料,并直接在浏覽器中呈現頁面
2. 什麼是路由?
路由是根據不同的 URL 位址展示不同的内容或頁面
在 SPA 應用中,大部分頁面結果不改變,隻改變部分内容的使用
前端路由的優缺點
優點
使用者體驗好,不需要每次都從伺服器全部擷取整個 HTML,快速展現給使用者
缺點
1.SPA 無法記住之前頁面滾動的位置,再次回到頁面時無法記住滾動的位置
2.使用浏覽器的前進和後退鍵會重新請求,沒有合理利用緩存
3. 路由的原理
前端路由的主要依靠的時 history ,也就是浏覽器的曆史記錄
history 是 BOM 對象下的一個屬性,在 H5 中新增了一些操作 history 的 API
浏覽器的曆史記錄就類似于一個棧的資料結構,前進就相當于入棧,後退就相當于出棧
并且曆史記錄上可以采用 listen 來監聽請求路由的改變,進而判斷是否改變路徑
在 H5 中新增了 createBrowserHistory 的 API ,用于建立一個 history 棧,允許我們手動操作浏覽器的曆史記錄
新增 API:pushState ,replaceState,原理類似于 Hash 實作。 用 H5 實作,單頁路由的 URL 不會多出一個 # 号,這樣會更加的美觀
4. 路由的基本使用
react-router-dom 的了解和使用
專門給 web 人員使用的庫
1.一個 react 的倉庫
2.很常用,基本是每個應用都會使用的這個庫
3.專門來實作 SPA 應用
首先我們要明确好頁面的布局 ,分好導航區、展示區
要引入 react-router-dom 庫,暴露一些屬性 Link、BrowserRouter...
import { Link, BrowserRouter, Route } from 'react-router-dom'
導航區的 a 标簽改為 Link 标簽
<Link className="list-group-item" to="/about">About</Link>
同時我們需要用 Route 标簽,來進行路徑的比對,進而實作不同路徑的元件切換
<Route path="/about" component={About}></Route>
<Route path="/home" component={Home}></Route>
這樣之後我們還需要一步,加個路由器,在上面我們寫了兩組路由,同時還會報錯訓示我們需要添加 Router 來解決錯誤,這就是需要我們添加路由器來管理路由,如果我們在 Link 和 Route 中分别用路由器管理,那這樣是實作不了的,隻有在一個路由器的管理下才能進行頁面的跳轉工作。
是以我們也可以在 Link 和 Route 标簽的外層标簽采用 BrowserRouter 包裹,但是這樣當我們的路由過多時,我們要不停的更改标簽包裹的位置,是以我們可以這麼做
我們回到 App.jsx 目錄下的 index.js 檔案,将整個 App 元件标簽采用 BrowserRouter 标簽去包裹,這樣整個 App 元件都在一個路由器的管理下
// index.js
<BrowserRouter>
< App />
</BrowserRouter>
5. 路由元件和一般元件
在我們前面的内容中,我們是把元件 Home 群組件 About 當成是一般元件來使用,我們将它們寫在了 src 目錄下的 components 檔案夾下,但是我們又會發現它和普通的元件又有點不同,對于普通元件而言,我們在引入它們的時候我們是通過标簽的形式來引用的。但是在上面我們可以看到,我們把它當作路由來引用時,我們是通過 {Home} 來引用的。
從這一點我們就可以認定一般元件和路由元件存在着差異
首先它們的寫法不同
一般元件:<Demo/>,路由元件:<Route path="/demo" component={Demo}/>
同時為了規範我們的書寫,一般将路由元件放在 pages 檔案夾中,路由元件放在 components
而最重要的一點就是它們接收到的 props 不同,在一般元件中,如果我們不進行傳遞,就不會收到值。而對于路由元件而言,它會接收到 3 個固定屬性 history 、location 以及 match
6. NavLink 标簽
NavLink 标簽是和 Link 标簽作用相同的,但是它又比 Link 更加強大。
在前面的 demo 展示中,你可能會發現點選的按鈕并沒有出現高亮的效果,正常情況下我們給标簽多添加一個 active 的類就可以實作高亮的效果
而 NavLink 标簽正可以幫助我們實作這一步
當我們選中某個 NavLink 标簽時,就會自動的在類上添加一個 active 屬性
<NavLink className="list-group-item" to="/about">About</NavLink>
我們可以看到左側的元素類名在不斷的切換,當然 NavLink 标簽是預設的添加上 active 類,我們也可以改變它,在标簽上添加一個屬性 activeClassName
例如 activeClassName="aaa" 在觸發這個 NavLink 時,會自動添加一個 aaa 類
🥩 7. NavLink 封裝
在上面的 NavLink 标簽種,我們可以發現我們每次都需要重複的去寫這些樣式名稱或者是 activeClassName ,這并不是一個很好的情況,代碼過于備援。那我們是不是可以想想辦法封裝一下它們呢?
我們可以采用 MyNavLink 元件,對 NavLink 進行封裝
首先我們需要建立一個 MyNavLink 元件
return 一個結構
<NavLink className="list-group-item" {...this.props} />
首先,有一點非常重要的是,我們在标簽體内寫的内容都會成為一個 children 屬性,是以我們在調用 MyNavLink 時,在标簽體中寫的内容,都會成為 props 中的一部分,進而能夠實作
接下來我們在調用時,直接寫
<MyNavLink to="/home">home</MyNavLink>