React-Router 中文簡明教程(上)

概述

提及 前端路由,若是你用過前端 MV* 框架構建 SPA 應用(單頁面應用),對此必定不陌生。html

傳統開發中的 路由,是由服務端根據不一樣的用戶請求地址 URL,返回不一樣內容的頁面,而前端路由則將這些任務經過 JS 在瀏覽器端完成,SPA 應用 則是前端路由的最佳適用場景,由於它結構簡單,只需更新頁面部分顯示內容 也沒必要每次都從服務端獲取內容。前端

react-router 是官方指定和維護的 React 路由庫,它經過管理 URL,實現組件間切換,和狀態 (state) 的變化。node

準備工做

官方示例教程 react-router-tutorial 寫的貼心又詳細,一共14節,本文內容以官方教程爲準,分紅三章:react

在學習前,須要你對 React 的 JSX 語法有初步的認識,若是瞭解 ES6 語法更好,後續的 React 系列教程我都會用 ES6 來寫。建議初學者跟着教程 碼一遍代碼~ 爲了照顧初學者,我寫的可能會囉嗦些,大神勿噴~webpack

首先你須要安裝 Node.js 和 npm 包管理工具,命令行工具推薦 Git。瀏覽器不能直接解析 JSX 和 ES6 語法,因此須要一個編譯打包工具 這裏選擇 webpack,全局安裝 webpack —— 命令行輸入:git

npm install webpack -g

建立項目目錄:react-router-tutorial,
接着分別建立:文件夾module,index.html,index.js(入口文件),
package.json(定義了項目所需的各個模塊,和配置信息)
webpack.config.js(webpack 配置文件),目錄結構以下:
es6

下載以上目錄文件github

index.html:web

 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>My First React Router App</title>
 6 </head>
 7 <body>
 8     <div id=app></div>
 9     <!-- 編譯後的js文件 -->
10     <script src="bundle.js"></script>
11 </body>
12 </html>

package.json:
其中 npm start 爲 Node.js 啓動模塊的默認命令,這裏用 webpack-dev-server 來運行一個小型 Node.js Express 服務器,它會實時將代碼編譯打包在內存中(注意:這個過程並不會在你的項目文件夾裏 產生任何文件)
啓動項目時,只需在命令行輸入npm start,訪問http://localhost:8080/index.html便可瀏覽結果。
npm

 1 {
 2   "name": "tutorial",
 3   "version": "1.0.0",
 4   "description": "",
 5   "main": "index.js",
 6   "scripts": {
 7     "start": "webpack-dev-server --inline --hot --content-base ."
 8   },
 9   "author": "",
10   "license": "ISC",
11   "dependencies": {
12     "react": "^0.14.7",
13     "react-dom": "^0.14.7",
14     "react-router": "^2.0.0"
15   },
16   "devDependencies": {
17     "babel-core": "^6.5.1",
18     "babel-loader": "^6.2.2",
19     "babel-preset-es2015": "^6.5.0",
20     "babel-preset-react": "^6.5.0",
21     "http-server": "^0.8.5",
22     "webpack": "^1.12.13",
23     "webpack-dev-server": "^1.14.1"
24   }
25 }

webpack.config.js:

 1 module.exports = {
 2     // 入口文件
 3     entry: './index.js',
 4 
 5     // 輸出文件
 6     output: {
 7         filename: 'bundle.js',
 8         publicPath: ''
 9     },
10 
11     module: {
12         loaders: [
13             // 匹配到js或jsx文件後 使用 babel-loader 來處理
14             // '?'後面是該loader的參數設置(使用了es6和react轉碼器)
15             {
16                 test: /\.js[x]?$/,
17                 exclude: /node_modules/,
18                 loader: 'babel-loader?presets[]=es2015&presets[]=react'
19             }
20         ]
21     }
22 };

如今來 安裝package.json中全部的 依賴模塊,命令行輸入:

npm install

上個廁所或喝杯咖啡 一會就行了,若是你還感受安裝過程慢,也能夠換成淘寶鏡像的安裝方式(先安裝鏡像命令):

npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install

一. 啓動應用

建立modules/App.js

App.js:

import React from 'react';

// 定義App組件
export default class App extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <h1>React Router Tutorial</h1>
        );
    }
}

使用 ES6 的import語句代替以前的require()方法來導入模塊,使用class來建立」類」(js中根本不存在類,class只是語法糖)extends用來繼承React.Component,constructor(){}爲構造函數方法,export default定義了模塊對外的接口 也就是」類」App,這裏定義了一個叫 APP 的根組件

若是你對 ES6 的寫法感到困惑,能夠看下這篇文章:如何將 react 中的 ES5 寫法轉化成 ES6

在入口文件index.js中導入App組件 並將它渲染到id爲app的容器裏:

index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './modules/App';

ReactDOM.render(
    <App/>,
    document.getElementById('app')
);

啓動應用:

npm start

瀏覽器打開http://localhost:8080/index.html就能夠看到如下結果:

ok, 第一個 React 應用啓動成功~ 下面將開始 react-router 的部分。

二. 建立一個簡單的路由

Router 也是一個組件,但它不會被用來渲染任何內容

ReactDOM.render(<Router/>, document.getElementById('app'))

修改 index.js
1. 導入Router,Route,hashHistory
2. 在render中用Router代替App

下面代碼中的import { Router, Route, hashHistory }是ES6導入模塊的另外一種用法,大括號中指定了從react-router模塊裏導入的變量名,變量名必須與被導入模塊對外接口的名稱相同。

import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, hashHistory } from 'react-router'
import App from './modules/App';

ReactDOM.render((
    <Router history={hashHistory}>
        <Route path="/" component={App}/>
    </Router>
), document.getElementById('app'));

啓動應用npm start,訪問http://localhost:8080,會看到和上一節同樣的結果,瀏覽器地址欄變成了http://localhost:8080/#/?_k=bw8nlm,這個稍後解釋~

Router 組件 使用了hashHistory管理路由的歷史,經過監聽切換 URL 的 hash 變化來動態渲染組件。
這裏的path=」/」 表明根路徑,component={App} 意思是渲染組件 App。
當用戶訪問http://localhost:8080或http://localhost:8080/#/時,組件App將被渲染到document.getElementById(‘app’)中。

建立2個新組件:modules/About.js,modules/Repos.js

About.js:

 1 import React from 'react';
 2 
 3 export default class About extends React.Component {
 4     constructor(props) {
 5         super(props);
 6     }
 7 
 8     render() {
 9         return (
10             <div1>About</div>
11         );
12     }
13 }

Repos.js:

 1 import React from 'react';
 2 
 3 export default class Repos extends React.Component {
 4     constructor(props) {
 5         super(props);
 6     }
 7 
 8     render() {
 9         return (
10             <div>Repos</div>
11         );
12     }
13 }

而後,修改 index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, hashHistory } from 'react-router'
import App from './modules/App';
// 增長 About 和 Repos 組件
import About from './modules/About'
import Repos from './modules/Repos'

// 增長2個新路由
ReactDOM.render((
    <Router history={hashHistory}>
        <Route path="/" component={App}/>
        <Route path="/about" component={About}/>
        <Route path="/repos" component={Repos}/>
    </Router>
), document.getElementById('app'));

Route 組件能夠定義多個路由,訪問http://localhost:8080/#/about和http://localhost:8080/#/reops會看到瀏覽中分別渲染About和Repos組件,可見path屬性值定義了 URL 中 #號 以後的路徑參數

三. 導航連接 Link 組件

Link 組件 幾乎等同於<a/>標籤,是應用中較經常使用的組件

修改 App.js,在組件App中增長一個導航:

 1 import React from 'react';
 2 // 導入Link組件
 3 import { Link } from 'react-router';
 4 
 5 export default class App extends React.Component {
 6     constructor(props) {
 7         super(props);
 8     }
 9 
10     render() {
11         return (
12             <div>
13                 <h1>React Router Tutorial</h1>
14                 <ul role="nav">
15                     <li><Link to="/about">About</Link></li>
16                     <li><Link to="/repos">Repos</Link></li>
17                 </ul>
18             </div>
19         );
20     }
21 }

Link 組件中的to屬性定義了 URL 中 #號 以後的路徑參數,因此要和 Route 組件中的 path值相對應。
訪問http://localhost:8080看到以下結果:

點擊連接 About 會渲染組件 About,點瀏覽器的回退按鈕 會返回渲染根組件,再點擊 Repos 又會渲染組件Repos,看起來不錯~

四. 嵌套路由

上節中,咱們在組件App中添加了一個 導航<ul role=」nav」>…</ul>,但一般,導航應該在每一個視圖中都出現,在不使用 React Router 的狀況下,最簡單的辦法就是將<ul role=」nav」>…</ul>塞到每一個組件裏

但在應用變的複雜時,這個辦法顯然 不夠簡潔,因此 React 提供了另外一個更好的解決辦法:嵌套路由,就是將Route 組件嵌套,分爲兩步:

第一步,修改 index.js,嵌套<Route/>:

 1 import React from 'react';
 2 import ReactDOM from 'react-dom';
 3 import { Router, Route, hashHistory } from 'react-router'
 4 import App from './modules/App';
 5 import About from './modules/About'
 6 import Repos from './modules/Repos'
 7 
 8 ReactDOM.render((
 9     <Router history={hashHistory}>
10         <Route path="/" component={App}>
11             <Route path="/about" component={About}/>
12             <Route path="/repos" component={Repos}/>
13         </Route>
14     </Router>
15 ), document.getElementById('app'));

第二步,修改 App.js,在App組件內部經過this.props.children屬性嵌套進子組件:

 1 import React from 'react';
 2 import { Link } from 'react-router';
 3 
 4 // 增長 this.props.children 用來渲染子組件
 5 export default class App extends React.Component {
 6     constructor(props) {
 7         super(props);
 8     }
 9 
10     render() {
11         return (
12             <div>
13                 <h1>React Router Tutorial</h1>
14                 <ul role="nav">
15                     <li><Link to="/about">About</Link></li>
16                     <li><Link to="/repos">Repos</Link></li>
17                 </ul>
18             </div>
19 
20             {this.props.children}
21         );
22     }
23 }

index.js中<Route path=」/about」 component={About}/>和 <Route path=」/repos」 component={Repos}/>就成爲<Route path=」/」 component={App}/>的子路由。訪問http://localhost:8080,會先渲染App組件,點擊About 後,會在App組件內部渲染About組件。

一樣的,當用戶訪問http://localhost:8080/#/about時,先渲染App組件,而後在內部渲染About組件:

1 <App>
2   <About/>
3 </App>
4 
5 <App>
6   <Repos/>
7 </App>

本篇示例源碼:
react-router-demo-part1

相關文章
相關標籤/搜索