版權聲明:本文爲博主原創文章,未經博主容許不得轉載。javascript
PS:轉載請註明出處 做者:TigerChain 地址:http://www.jianshu.com/p/b55cf53e633a 本文出自 TigerChain簡書css
React 教程系列html
教程簡介前端
本篇教程適合初學者,老鳥直接略過,若是有誤,歡迎指出,謝謝。java
二、教程難度node
初級react
三、Demo 地址:github.com/githubchen0…webpack
四、正文git
路由是什麼咱們可能不太理解,可是我說一個東西咱們必定知道,就是"路由器",路由器的功能用一句話歸納就是:數據從一個網絡到另外一個網絡就是靠路由來完成的[固然路由器的功能不只僅於此]。github
咱們說的程序開發中的路由不是指路由器和網絡協議中的路由,可是基本思想是同樣的。而路由又能夠分爲前端路由和後端路由。
咱們來看一個路由的簡易圖吧,有了這個圖,你們對路由就有一個大體的瞭解了。
一、後端路由
舉個栗子,分配一個站點,服務器地址是: http://192.168.1.200:8080 ,在這個網站中提供了三個界面,分別是:
http://192.168.1.200:8080/index.html
http://192.168.1.200:8080/about/aboutus.html
http://192.168.1.200:8080/feedback.html
複製代碼
當咱們在瀏覽器中敲入 http://192.168.1.200:8080/index.html 來訪問頁面時,web 服務器接收到這個請求,而後把 /index.html 解析出來,而後找到 index.html 並展現出來,這就是路由分發,路由的分發是經過路由來完成的。
二、前端路由
雖然前端路由和後端路由在實現技術上差異,可是原理都 TM 的同樣。在 H5 的 history Api 以前,前端的路由功能都是使用經過 hash「散列值得」 來實現的。 hash 能兼容低版本的瀏覽器。好比:
http://192.168.1.200:8080/#/index.html
http://192.168.1.200:8080/#/about/aboutus.html
http://192.168.1.200:8080/#/feedback.html
複製代碼
因爲 web 服務不會解析 # 後面的東西,但是 js 是能夠拿到 # 後面的東西的,有一個方法就是 window.location.hash 來讀取,經過這個方法來匹配不一樣的功能上。
PS 咱們進一步來講,舉個例子,有一個地址爲:
http://www.xxx.com/path/a/b/c.html?key1=Tiger && key2=Chain && key3=fuck#/path/d/e.html
複製代碼
http:協議
www.xxx.com:域名
/path/a/b/c.html:路徑,即服務器上的資源
?key1=Tiger && key2=Chain && key3=fuck:這個很好理解 Get 請求的參數
#/path/d/e.html:hash 也叫散列值,也叫錨點
複製代碼
上面的 hash 是和瀏覽器交互的,其它的都是和服務器進行交互的。
先看咱們要完成的效果:
咱們看到了 hash 的改變不會致使瀏覽器的刷新,而且咱們使用原生的 JS 定義了一個簡單的 SPA 「單頁應用」。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title> HashDemo </title>
</head>
<body>
<h3>我是 Hash 的一個 Demo</h3>
<hr />
<a href="#hash1">#hash1</a>
<a href="#hash2">#hash2</a>
<a href="#hash3">#hash3</a>
<a href="#hash4">#hash4</a>
<p/>
<div id = "show-hash-result" style="color:blue">
點擊上面連接,並觀察瀏覽器
</div>
<h4>自定義一個簡單的單面路由頁</h4>
<div id="nav">
<ul>
<li><a href="#/index.html">首頁</a></li>
<li><a href="#/server">服務</a></li>
<li><a href="#/mine">個人</a></li>
</ul>
</div>
<div id="result"></div>
<style> #nav { margin: 0; border: 0; height: 40px; width: 300px; border-top: #060 2px solid; margin-top: 10px; border-bottom: #060 2px solid; background-color: #690; } #nav ul { margin: 0; border: 0; list-style: none; line-height: 40px; } #nav li { display: block; float: left; } #nav a { display: block; color: #fff; text-decoration: none; padding: 0 20px; } #nav a:hover { background-color: #060; } </style>
<script type="text/javascript"> window.addEventListener("hashchange", function(){ //變化後輸出當前地址欄中的值 document.getElementById("show-hash-result").innerHTML = location.hash; console.log(window.location.hash) ; }); </script>
<script type="text/javascript"> //自定義一個路由規則 function CustomRouter(){ this.routes = {}; this.curUrl = ''; this.route = function(path, callback){ this.routes[path] = callback || function(){}; }; this.refresh = function(){ this.curUrl = location.hash.slice(1) || '/'; if(this.curUrl.indexOf('/')!=-1){ //這裏粗略的把 hash 過濾掉 this.routes[this.curUrl](); } }; this.init = function(){ window.addEventListener('load', this.refresh.bind(this), false); window.addEventListener('hashchange', this.refresh.bind(this), false); } } //使用路由規則 var R = new CustomRouter(); R.init(); var res = document.getElementById('result'); R.route('/hash1',function () { document.getElementById("show-hash-result").innerHTML = location.hash; }) R.route('/index.html', function() { res.style.height='150px'; res.style.width='300px'; res.style.background = 'green'; res.innerHTML = '<html>我是首頁</html>'; }); R.route('/server', function() { res.style.height='150px'; res.style.width='300px'; res.style.background = 'orange'; res.innerHTML = '我是服務頁面'; }); R.route('/mine', function() { res.style.background = 'red'; res.style.height='150px'; res.style.width='300px'; res.innerHTML = '個人界面'; }); </script>
</body>
</html>
複製代碼
代碼沒有整理和抽取,感興趣的能夠再深層次的去改 「改到你滿意爲止」。
window 的 history 提供了對瀏覽器歷史記錄的訪問功能,而且它暴露了一些方法和屬性,讓你在歷史記錄中自由的前進和後退,而且在 H5 中還能夠操做歷史記錄中的數據。
history 的 API 以下:
interface History {
readonly attribute long length;
readonly attribute any state;
void go(optional long delta);
void back();
void forward();
//h5 引進如下兩個方法
void pushState(any data, DOMString title, optional DOMString? url = null);
void replaceState(any data, DOMString title, optional DOMString? url = null);
};
複製代碼
back()
:在歷史記錄是後退history.back() ;
複製代碼
forward()
:在歷史記錄中前進history.forward();
複製代碼
go()
:移動到指定的歷史記錄點history.go(-1)
複製代碼
length
:爲 history 的屬性,顯示 history 的長度關於 h5 的 history 推薦看這裏,詳細的講解了 history,很是值得的看。
這裏重點說 h5 的 pushState,徹底代替 hash 而且更優雅。
廢話很少說,直接上效果圖
以上咱們實現了一個很是簡單的 SPA ,咱們能夠看到咱們使用 histoy pushState 和 onpopstate 實現和上面 hash 同樣的功能。
源碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title> H5 HistoryDemo </title>
</head>
<body>
<ul>
<li><a onclick="home()">首頁</a></li>
<li><a onclick="about()">關於</a></li>
<li><a onclick="mine()">個人</a></li>
</ul>
<div id="showContent" style="height:250px;width:200px;background:green">home</div>
<script> function home() { history.pushState({name:'home',id:1}, null, "?page=home"); showCard("home"); } function about() { history.pushState({ id:2, name:"about" },null,"?page=about") ; showCard("about"); } function mine() { history.pushState({ id:3, name:"mine" },null,"?name=chen&age=30") ; showCard("mine"); } function showCard(name) { document.getElementById("showContent").innerHTML = name; } //點擊返回鍵盤的時候顯示歷史 window.onpopstate = function (event) { var content = ""; if(event.state) { content = event.state.name; } showCard(content); } </script>
</body>
</html>
複製代碼
PS:基於 h5 history 實現的路由和最初的路由基本上一致。
http://192.168.1.200:8080/index
http://192.168.1.200:8080/about/aboutus
http://192.168.1.200:8080/feedback
複製代碼
從性能上來講,後端路由每次向 server 發起一個請求,server 要解析響應,就會有延時,而前端路由只是變換了一下路徑,沒有網絡延時這一說,因此性能「用戶體驗」是大大的提高了。
通過以上咱們對路由有了一個大致的理解,咱們接下來講咱們的重點 React 的路由功能。
React 官方沒有給出一個明確的組件,推薦使用三方的一個叫 React Router 的組件。「固然咱們不使用 React Router 也能夠完成路由功能,好比傳統的 hash 功能,沒有問題,可是用了它就很是方便和好用」。
咱們都是知道 React 玩的就是組件化,因此 React Router 也是一個組件。
一、廢話很少說,咱們直接寫一個簡單的 SPA Demo 感覺一下
效果以下:
從圖能夠看到咱們使用 React router 實現一個簡單的 SPA 應用。若是你們細心看了前面的知識點,這個沒有什麼好說的。
二、下面咱們擼碼,經過代碼來直觀的感覺一下 「此次我使用的是 windows 開發,不過不影響,你能夠直接在 mac 開發」。
好比:
D:\study\react-study\lesson03\reactrouter\reactrouterdemo
複製代碼
進入到 reactrouterdemo 目錄中建立項目
yarn init // 一路回車便可
yarn add react react-dom webpack webpack-dev-server babel-core babel-loader babel-preset-es2015 babel-preset-react babel-preset-stage-0 --dev //安裝依賴的插件,不清楚,能夠看 webpack 這一節
複製代碼
而後每一個文件中對應的內容
.babelrc
# .babelrc
{
"presets": ["react", "es2015","stage-0"]
}
複製代碼
webpack.config.js
# webpack.config.js
module.exports = {
entry: __dirname + "/app/main.js",//已屢次說起的惟一入口文件
output: {
path: __dirname + "/public",//打包後的文件存放的地方
filename: "bundle.js"//打包後輸出文件的文件名
},
devServer:{
contentBase: "./public",//本地服務器所加載的頁面所在的目錄
// colors: true,//終端中輸出結果爲彩色
historyApiFallback: true,//不跳轉
inline: true//實時刷新
},
//新增長部分
module:{
loaders:[
//babel配置
{
test:/\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
}
}
複製代碼
index.html
# index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ReactRouter Demo</title>
</head>
<body>
<div id="container"></div>
<script src="bundle.js"></script>
</body>
</html>
複製代碼
這沒有什麼好說的,若是看過 webpack 等章節,咱們就很快的建立這些東西。
接下來咱們安裝 react-router
yarn add react-router --dev
複製代碼
# main.js
import React from 'react' ;
import ReactDOM from 'react-dom' ;
import { Router, Route, Link ,hashHistory} from 'react-router';
/**
* 定義 Home 組件
* @type {String}
*/
class Home extends React.Component{
render(){
return(<div>
Home
</div>) ;
}
}
/**
* 定義 About 子頁面組件
* @type {String}
*/
class About extends React.Component{
render(){
return(
<div>About</div>
) ;
}
}
class App extends React.Component {
render() {
return (
<div>
<h1>App</h1>
<ul>
<li><Link to="/home">首頁</Link></li>
<li><Link to="/about">關於我</Link></li>
</ul>
</div>
);
}
}
ReactDOM.render((
<Router>
<Route path="/" component={App}/>
<Route path="/home" component={Home} />
<Route path="/about" component={About} />
</Router>
), document.getElementById('container'));
複製代碼
最後配置 package.json 文件的腳本,添加下面一句。
package.json
"scripts": {
"start": "webpack-dev-server --progress --port 8888"
}
複製代碼
好了,到此爲止咱們基本上寫完一個簡單的 SPA 頁面了,讓咱們來驗證一下吧,咱們在命令行中輸入 yarn start,一切 ok ,咱們打開瀏覽器輸入 localhost:8888,若是沒有什麼大問題,你毛也看不到,這個時候不要慌,打開 chrome 調試工具 「別給我說你沒有使用 chorme 調試 web 頁面,若是沒有本身去面面壁」。結果以下
What The Fuck ,什麼鬼嗎,按照文檔 「這個翻譯文檔過期了」來的竟然出錯了,好吧,解決問題,把上面框出來的問題到 Google 上一搜,答案在這裏,來吧上一張圖
大致意思是說,若是你使用的 react-router v4 版本 「上一個穩定版本是 2.8.1」,那麼就要使用 react-router-dom,而且這是 v4 版本中的更新 「 v4 中有不少更新」。啥是react-router-dom 呢,你只要知道通常咱們前端就用這個包來進行WEB開發了,這一篇文章詳細的介紹了,也就是使用 react-router-dom 徹底能夠替代 react-router 。
PS: 若是你的項目中已經在使用react-router以前的版本,那必定要慎重的更新,由於新的版本是一次很是大的改動,若是你要更新,工做量並不小。關於 React-router 2.8 左右的版本能夠看阮一峯的:www.ruanyifeng.com/blog/2016/0… 文章,很是好。
上面說了,react-router-dom 能夠迭代 react-router ,那麼咱們先把 react-router 卸載了,而後安裝 react-router-dom
yarn remove react-router //卸載 react-router
yarn add react-router-dom --dev
複製代碼
而後修改 main.js,這裏只修改一句話:
將 mport { Router, Route, Link } from 'react-router'; 修改成
import {
BrowserRouter as Router,
Route,
Link
} from 'react-router-dom';
複製代碼
而後看結果,仍是出不來,看 chorme 的輸出臺,這下變了,不是上面的錯誤了,而是
大概意思就是 標籤只能有一個子元素,這好辦,加一個 div 不就搞定了。
修改地方是 :
而後再看結果,神奇般出來了咱們開頭的效果,真不容易呀。
總結:咱們在開發 web 頁面的時候就使用 react-router-dom 來代替之前的 react-router 就能夠了。他們的用法稍微有不一樣:
以上咱們就簡單的開發一個 React-router 的 SPA ,咱們對 React-router v4 也有了一個大概的解,下面咱們具體說說 React-router v4 的一些用法吧。
到此爲止,咱們對 react router 有一個大致的認識,下一節們再詳細的說說 react-router v4 的一些用法。
一、react-router v4 沒有嵌套之用法了
二、傳遞參數「url 傳參」
通過上面的瞭解咱們知道,React-router v4 中,咱們在 Router 組件中能夠寫任意的標籤,可是隻能有一個根標籤。
url 傳參,咱們使用通配符 :id ,下面咱們結合代碼一塊兒看看。
# main.js
import React from 'react' ;
import ReactDOM from 'react-dom' ;
import {
BrowserRouter as Router,
Route,
HashRouter,
Link
} from 'react-router-dom';
/**
* 定義 Home 組件
* @type {String}
*/
class Home extends React.Component{
render(){
return(<div>
Home
</div>) ;
}
}
/**
* 定義 About 子頁面組件
* @type {String}
*/
class About extends React.Component{
render(){
return(
<div>About</div>
) ;
}
}
class App extends React.Component {
render() {
return (
<div>
<h1>App</h1>
<ul>
<li><Link to="/home">首頁</Link></li>
<li><Link to="/about">關於我</Link></li>
<li><Link to="/haha">haha</Link></li>
</ul>
</div>
);
}
}
// 在 react-router v4.0 中獲取 接收參數使用 this.props.match.params.屬性名字
class Haha extends React.Component{
render(){
return(
<div>
<h3> ID: {this.props.match.params.id}</h3>
match.url: {this.props.match.url}
</div>
) ;
}
}
// 無狀態的組件
// const Haha = ({ match }) => (
// <div>
// <h3>ID: {match.params.id}</h3>
// </div>
// )
ReactDOM.render((
<HashRouter>
<div>
<Route path="/" component={App}/>
<Route path="/home" component={Home} />
<Route path="/about" component={About} />
<Route path="/:id" component={Haha}/>
</div>
</HashRouter>
), document.getElementById('container'));
複製代碼
經過上圖咱們能夠看到 :id 匹配的是 home,about,haha,咱們再看 chorme 調試工具,很清楚的看到 li 標籤中的 link 其實就是一個 a 標籤,to 就至關於 href 屬性。
細習的朋友可能發現了,我這裏使用 HashRouter 代替了 Router,那麼這個有什麼做用呢,答案就是在上面的運行結果中,咱們看到點擊首頁等連接的時候,地址欄中自動加了一個 # ,也就說 HashRouter 是前面的說的 hash 的方式實現路由。
如何取得 id 的參數呢,咱們經過
his.props.match.params.id
複製代碼
來取得,這裏的 id 就是你 :id 中的 id ,名字能夠本身改。
一、本實例咱們基於 ant design 來仿一下 ant design「如下簡稱 antd」 的網站「體驗一下 spa 應用中 react-router的應用,本次選用 react-router@2.8.1 來開發」
對 ant design 不瞭解的能夠看看官方:ant.design/index-cn,它是一個 UI 設計語言相似於 bootstrap ,而且它和 react 無縫結合
首先咱們來看一下 ant design 的官網界面以下:
再來看看,咱們仿的界面:
怎麼樣,大致上仍是很像的吧,固然我只是爲了演示 react-router 在 spa 應用中的應用,仿的確定和原生沒有百分百同樣「css 若是要作的好,就要花費大量的時間和精力,本人的 css 能力仍是很薄弱的」
二、好我廢話很少,咱們直接開始擼代碼吧「在 mac 環境下,win 下是同樣的」
mkdir antddemo
cd antddemo
yarn init
複製代碼
而後一路回車便可
├── index.html
├── package.json
├── src
│ ├── imgs
│ ├── js
│ │ ├── component
│ │ └── index.js
│ └── styles
├── webpack.config.js
├── yarn-error.log
└── yarn.lock
複製代碼
PS: index.js 就咱們的入口 js 文件,imgs 用來存放本地圖片,styles 用來放 css 文件,component 用來存放編寫的 react 組件的
yarn add react react-dom //回車,繼續安裝
yarn add babel-core babel-loader babel-preset-es2015 babel-preset-react babel-preset-stage-0 webpack webpack-dev-server style-loader url-loader css-loader antd react-hot-loader react-router@2.8.1 --dev
複製代碼
而後回車沒有什麼問題即就顯示安裝成功,我這裏一口氣所須要的依賴都安裝好了,你也能夠分別來安裝。
{
"presets":["react","stage-0","es2015"],
"plugins": [
["import", { "libraryName": "antd", "style": "css" }]
]
}
複製代碼
其中的 plugin 是配置 antd 的,具體能夠看官網,這裏大概說一下,根據前面的經驗咱們知道一個 css 樣式是能夠被 import 進來的,若是咱們添加了 css-loader 和 style-loader 的話,若是 antd 想被 import 引入來使用的話,咱們還須要安裝一個插件 babel-plugin-import「也是官司方推薦的」,具體能夠看官方的按須要加載這一小結:ant.design/docs/react/…
下面咱們安裝 babel-plugin-import
yarn add babel-plugin-import --dev
複製代碼
ps:.babelrc 裏面的 plugin 就是 配置 babel-plugin-import 這玩意的
# webpack.config.js
module.exports = {
entry: __dirname + "/src/js/index.js",
output: {
path: __dirname + "/src/", //打包後文件地址
publicPath:"/src/", //命令行模式下,必定要配置output.publicPath來指定編譯後的包(bundle)的訪問位置.
filename: "bundle.js" //打包後文件
},
module: {
loaders: [
//babel配置
{
test:/\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
// 爲了避免和 antd css 樣式衝突,咱們
{
test: /\.css$/,
loader: 'css-loader?sourceMap&modules&localIdentName=[local]___[hash:base64:5]!!',
exclude: /node_modules/
},
// style-loader css-loader 配置
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
//加載本地圖片 配置 url-loader
{test:/\.(png|jpg)$/,loader:"url-loader?limit=8192&name=img/[name][hash:8].[ext]"
}
]
},
devServer:{
hot:true,
historyApiFallback: true,//不跳轉
inline: true//實時刷新
}
}
複製代碼
PS:這裏要注意一點,由咱們安裝了 css-loader 和 antd ,咱們須要對 antd 單獨配置一下,就是把 node_modules 下的文件都 exclude 掉,不要讓它走 css-modules,不然 css-loader 會把 antd 的 css 樣式所有沖掉「你引入的 antd 樣式死活都加載不出來,切記、切記、切記」,具體能夠看這裏:github.com/ant-design/…
以上咱們只是搭建了一個架子,那麼既然 react 牛 b 的地方就是組件化,咱們就把 antd 網頁劃分一下組件吧,由 antd 官網咱們能夠看到,上面底部和底部是不變的,咱們能夠分別抽出一個組件來,具體組件劃分以下:
由上圖咱們看到 antd 大致來講就分爲這四個組件。並用只有內容區域是變化的,其它組件不變
# index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="src/styles/pc.css">
<link rel="stylesheet" href="src/styles/main.css">
<link rel="stylesheet" href="src/styles/common.css">
</head>
<body>
<div id="container"></div>
<script type="text/javascript" src="./src/bundle.js"> </script>
</body>
</html>
複製代碼
和咱們之前的 index.html 基本上沒有什麼區別,只不過咱們引入幾個 css 樣式而已
# index.js
import React,{Component} from 'react' ;
import ReactDOM from 'react-dom' ;
// 這裏咱們使用 react-router 2.8.1
import {hashHistory,Router,Route,IndexRoute,Link} from 'react-router' ;
//引入 pc 主界面組件
import PCIndex from './component/pc_index.js' ;
import AntdofReact from './component/antdofreact.js' ;
// 引入快速上手組件
import QuickStart from './component/quick_start.js' ;
//引入項目實踐組件
import ProjectPractice from './component/projectpractice.js' ;
//引入在 react 中使用組件
import UseInReact from './component/useinreact.js' ;
//引入自定義主題組件
import CustomTheme from './component/customtheme.js' ;
//引入更新日誌組件
import UpDateLog from './component/updatelog.js' ;
class Main extends React.Component {
render(){
return(
// 定義路由
<Router history={hashHistory}>
<Route path="/" component={PCIndex}>
<IndexRoute component={AntdofReact}></IndexRoute>
<Route path="react/getting-started-cn" component={QuickStart}></Route>
<Route path="react/practical-projects-cn" component={ProjectPractice}></Route>
<Route path="react/use-with-create-react-app-cn" component={UseInReact}></Route>
<Route path="react/customize-theme-cn" component={CustomTheme}></Route>
<Route path="react/changelog-cn" component={UpDateLog}></Route>
</Route>
</Router>
) ;
}
}
ReactDOM.render(
<Main />,document.getElementById('container')
) ;
複製代碼
在這裏咱們路由規則都定定出來了。
import React, { Component, PropTypes } from 'react';
// 導入頭部組件
import PCHeader from './pc_header.js' ;
//導入主體內容組件
import PCMAIN from './pc_main.js' ;
//導入底部組件
import PCFooter from './pc_footer.js' ;
//首頁 包含公共的頭部和底部
export default class PCIndex extends Component {
constructor(props) {
super(props);
}
render() {
//取得 PCIndex中的子組件 下句就至關於 const children = this.props.children
const {children} = this.props
return (
<div> <PCHeader /> <PCMAIN maincontent={children}/> <PCFooter /> </div> ); } } PCIndex.propTypes = { }; 複製代碼
咱們拿一個圖來直觀的看一下 pc_index.js 組件的組合做用
import React, { Component, PropTypes } from 'react';
import PCMenu from './pc_menu.js' ;
// 內容組件
export default class PCMain extends Component {
constructor(props) {
super(props);
}
render() {
const {maincontent} = this.props;
return (
<main className="main"> {/* 菜單 */} <div className="menu"> <PCMenu /> </div> {/* 內容 */} <div className="content"> {maincontent} </div> </main>
);
}
}
PCMain.propTypes = {
};
複製代碼
pc_main.js 組件也就是組合了菜單組件,和內容「也能夠定義成一個組件,本身試試吧,React 中一切皆組件」
此時變成這樣了,以下圖所示:
好了,以上就是核心代碼,若是一個個 js 去說沒有什麼意義,浪費時間,能夠自行下載 demo 體驗一下
PS:後記,咱們仿 antd 網站使用是的 React-router v2.8 來作的「讓你們體驗一下"曾今"(固然如今也很流行)流行的路由」,後面抽出時間,改爲 React-router v4 版本。
demo地址:github.com/githubchen0…
聽說每一個勤奮、努力、想成爲牛 b 的人會點一個喜歡的