React 基礎中,我們都是用引包的方式,這裏我們需要先搭建一個 React 腳手架。
所謂腳手架,說白了就是能夠幫助你快速的來搭建一個環境,這樣你就可以直接來開發東西了,它會給你一些最常用的功能,比如測試,發佈,包括開發期間各種各樣的一些工作。
首先,我們需要安裝官方(fackbook)推出的 React 腳手架:
npm i -g create-react-app
然後創建一個項目:create-react-app react-demo
它現在就在幫我們裝 react,react-dom,react-scripts。那麼 react-scripts 是什麼呢?
事實上來說,我們一般開發也用不着這個東西。它在這裏的作用,就是把這個工程配置好了,打好包,供你直接下載就用,它的名字就叫 react-scripts。
換句話來說,create-react-app 其實只是一個外殼,它自己什麼也沒有。你真正需要這個項目的時候,它其實是幫助你從git官網上去下載 react-scripts,也就是它配好的項目。
順便一說,React 它官網有自己的 node.js 包管理器 yarn。其實它官方是比較推薦用 yarn 來下載它的各種依賴的。
其實你用 yarn 和 npm 都行,它不是強制的。只不過它默認的情況下,它會用 yarn 給你下初期的這些包,所以你後期如果在拿 npm 去裝東西的話,會導致包的結構混亂掉。
其實很簡單,如果有這個情況發生,那麼你就直接把原來它下載的 node_modules 全刪了,然後拿 npm 重新下一遍,就可以避免這個問題了。
主要是因爲 npm 和 yarn,它們的包結構不一樣。
項目已經創建成功:
如果你的項目裏面有 yarn.lock 這個文件,那麼可以把它刪掉,沒啥用。它是在 yarn 安裝東西的過程中,它自己創建的一個文件。
.git 是版本控制的文件,也可以刪。因爲它是直接從 git 上來克隆的,所以說會留下這個東西。
然後我們再來看下它的 package.json 文件:
它把所有的配置,其實都隱藏在了 react-scripts 裏面,所以它的優點是比較乾淨。
而缺點,就是如果我想要去修改什麼配置,是沒有辦法做到的。所以它有 eject 這樣一個選項,就是彈出的意思。
eject 它其實可以把所有的配置以及模塊都導出出來,這樣的話,把東西都放到表面上,就便於我們去做自定義。
當然如果這些基本的足夠你用了,就不用去做這個事了,不然你的工程會變得特別龐大,特別亂。
那麼,我們來嘗試下 npm run eject:
然後它會問你一些問題:
它說 TypeScript,Sass,CSS Modules 如果它們都拿出來了之後,就不能用了,你確定要這樣嗎?
我們選擇 y,然後它就會安裝一些東西。
因爲以前都是歸 react-scripts 管,現在歸你管了,就需要一些東西來幫你。
然後現在再打開 package.json,就比較正常了:
那麼讓我們回到主題,路由這個東西到底是幹什麼的呢?
其實很簡單,如果你是一個小項目,就1,2個頁面,那麼 if else 怎麼做都行。但如果真的是一個很大的應用,那麼如果你是通過自己去管理這些模塊之間的關係,誰放上面,誰先出來,誰後出來,這將是一件很費勁的事。
所以路由這個東西,它的作用就是通過不同的地址,展現不同的組件,簡化單頁面應用的編寫。
簡單來說,就是幫助你來組織整個程序。就比如說你寫了首頁,登陸頁,註冊頁,詳情頁等等很多頁面,你都寫完了之後,你自己不負責調用它們,你就把它們放在那,而是由路由來幫助你來調用這些東西。
在 react-router 中,與它相關的有四大組件:
1,react-router:它負責管理路由之間的關聯,誰在前,誰在後,有沒有參數之類的事情。
2,react-router-dom:react-router 的 DOM 綁定版,也就是網頁中用的。
3,react-router-native:react-native 中用的。
4,react-router-config:它自己的相關配置。因爲一般情況下,我們用 react-router-dom 的話,路由表是直接寫在組件裏面的。如果你希望把它抽離出來,讓這個東西邏輯變得更清晰的話,你就可以用這個 react-router-config,它是一個專門幫助我們來靜態去做配置的一個庫。
略微瞭解之後,我們就先安裝它:npm install react-router-dom -D
這裏只裝一個 react-router-dom 就可以了。
因爲第一,我們是在 web 端來做,目前還沒有觸及 RN。
第二,你在裝 react-router-dom 的時候,它會自己帶上 react-router,不用你再去裝一遍。
接下來,我們來看下它的使用:
react-router-dom 裏面一共有三大對象:
首先它包括三個大組件:Router,Route,Link。
Router 組件主要是一個包裹。它包在所有路由的配置之外,它是最外層的。
Route 是路由的一個配置項。如果說 Router 是一個數組的話,那 Route 它就相當於數組裏面的一個個元素。
Link 其實就是以前的 a 標籤,它負責幫我們來跳轉路由。當然,路由的跳轉一般來說有兩種方法,既可以用 js 來做跳轉,也可以直接用Link,就看你需要。(Link 最終也會被編譯成 a 標籤。)
簡單來說:
Router 是最外層的,它只負責包裹這個東西。
Route 就是用來配置那個路由,我對應的是哪個組件,它的路徑是什麼,等等一系列的東西。
Link 就是用來作爲跳轉的按鈕。
而在 Router 裏面,它還包含 BrowserRouter,HashRouter,MemoryRouter。這裏我們只做一個介紹,下一篇博客會細講。
BrowserRouter:基於 HTML5 的 historty API,直接以 path 形式呈現。需要注意的是,瀏覽器並未真正刷新,服務器也沒有對應的地址,除非刷新,否則服務器也不會接到請求。所以它適合配合服務器。
HashRouter:基於 location.hash,頁面不刷新。所以它是無法配合服務器使用的。
MemoryRouter:路由狀態保存在內存,刷新頁面會消失,所以它也無法配合服務器使用。
接下來就開始擼碼了,我們先把 src 目錄裏面原先東西清除掉,寫上我們自己的 demo:
我們一般將 Router 這個東西放到 index.js 裏面。因爲 App 就是在 index.js 裏面來進行聲明和初始化的。
那麼我如果想包住整個程序,那我是不是隻用把 App 包住就可以了?
首先,BrowserRouter 從名字就可以看出來,它是給瀏覽器用的 Router。
然後我個人一般習慣於起個別名,就叫做 Router。爲什麼呢?
因爲我們有的時候,是需要更換這個路由的。比如我現在不想用 BrowserRouter 了,我要換成 HashRouter 了,那我這時候就可以直接換,我底下所有的東西都不用改。
可以看到,這樣就很方便。
然後重點的路由邏輯就放到 App.js 裏面。
那麼既然我們在這裏要寫詳細的路由信息了,我們就需要另外的兩個東西:
那麼接下來,路由到底怎麼寫?
路由,它其實對應的是組件。
也就是說,如果你真想做路由的話,至少先得準備幾個組件。
我們在 src 目錄下創建一個新的目錄 components,並在裏面創建 3 個組件:
接下來,我們就需要在 App.js 裏面來聲明路由的關係。
在 <Route /> 裏面,至少需要兩個東西:
一個是 path,就是你的這個路由節點,它的路徑是什麼。
另一個是 component,就是當你碰到這個路徑的時候,你要找的是哪個組件。
但是現在還沒有完,還有一個小問題,就是路由它實際上來說,是能夠去兼容匹配的。什麼意思呢?
比如說我現在路由的路徑是 /course,那麼 path="/course" 肯定是會被識別到的,但是 path="/" 也能。爲什麼呢?
因爲你的 /course 裏面包括了 /,也就是說,所有的在我下面的,都包括。
比如,我現在的路徑是 "/course/2",但是實際上它能激活三個路由:
因爲它們前面都是相同的。路由只要從左邊開始能匹配到我,那就可以了。
所以爲了避免這種問題,怎麼辦呢?我們可以加一個 exact。
exact 翻譯過來就是精確的意思。
說白了,這個時候,你的路徑必須得跟我的一模一樣。加個 exact 就是精確匹配。
然後現在我們還少一點東西,目前我們現在還沒有辦法去跳轉。
因爲我們真正跳轉是需要 Link 的:
Link 也需要2個東西:
首先,你得在標籤裏面來一些文字,然後還要有個 to,就是去到哪個地址。
這時候就可以看到,頁面上有三個 a 鏈接,所以 Link 實際上編譯出來就是 a 標籤。
所以路由這個東西,實際上就是不同的地址,給你匹配不同的組件而已。