【原】react-router項目實戰

摘要:

  react-router相對於flux和redux來講,比較好容易理解一點和容易入門一點。這個是根據我以前的一個項目,而後我用react+react-router+webpack從新寫的。javascript

不過沒有所有寫完。只寫了一部分。不過用來實戰已經足夠了。html

不過因爲這個項目我主要是用來學習react-router,全部有些地方不必用路由的我仍是用了。因此若是要拿去用,這點要注意。前端

還有就是這個demo不是很完善,須要本身去完善一下。尤爲是一些目錄結構,因爲當時沒考慮好。因此能夠稍加完善java

 

注意點:此demo是根據react-router 1.0版原本寫的。以前版本的用法我沒有學過,是直接就學這個版本的。因此若是語法上跟各位的有區別的話,那應該是版本不一樣所致使的。react

固然,你們學習的話應該最好也以1.0版原本學,由於1.0版本相對來講是比較新和穩定的。並且拋棄了不少之前舊的語法,因此和之前版本的語法是有點區別的。目前好像正在出2.0了。技術的更新真的不是通常的快啊webpack

 

爲何要用路由?

我的理解的話,就前端而言,路由仍是由於單頁面應用時代的帶來而衍生出來的。當url發生變化時,路由相應的作出一些相應,從而來保證目前的url和要展現的界面一一對應好。git

 

效果圖以下:相似於微商城的一個網頁。點擊頁腳的不一樣位置,能夠切換不一樣的頁面。github

 

demo地址:https://github.com/xianyulaodi/React-routerweb

入口文件: render/app.js

 

 1 import React from 'react'
 2 import { render } from 'react-dom'
 3 import { Router, Route, IndexRoute, Link, IndexLink } from 'react-router'
 4 import { createHistory, useBasename } from 'history'
 5 
 6 
 7 import App from '../component/app.js'
 8 import Mall from '../component/routers/mall/mall.js'
 9 import Circle from '../component/routers/circle/circle.js'
10 import CircleType from '../component/routers/circle/circleType.js'
11 import My from '../component/routers/my/my.js'
12 import MyNav from '../component/routers/my/myNav.js'
13 import MyUserCenter from '../component/routers/my/userCenter.js'
14 import MemberClub from '../component/routers/my/memberClub.js'
15 import Index from '../component/routers/index/index.js'
16 import Type from '../component/routers/index/type.js'
17 import CircleTip from '../component/routers/circle/circleTip.js'
18 import CircleSay from '../component/routers/circle/circleSay.js'
19 
20 const history = useBasename(createHistory)({
21   basename: '/React-Router'
22 });
23 
24 {/**  {this.props.children}   很是重要**/}
25 {/** 思考:首頁也有其餘分路由,怎麼配**/ }
26 render((
27   <Router>
28     <Route path="/" component={App}>
29       <IndexRoute component={Index} />
30 
31       <Route path="/type/:typeName" component={Type} />
32 
33       <Route path="/mall" component={Mall}>
34           <Route path="type/:typeName" component={Type} />
35       </Route>
36 
37       <Route path="/my" component={My}>
38           <IndexRoute component={MyNav} />
39            <Route path="userCenter" component={MyUserCenter} />
40            <Route path="memberClub" component={MemberClub} />
41       </Route>
42 
43       <Route path="/circle" component={Circle}>
44           <IndexRoute component={CircleType} />
45           <Route path="tip/:tipName" component={CircleTip} />
46           <Route path="say" component={CircleSay} />
47       </Route>
48 
49     </Route>
50   </Router>
51 ), document.getElementById('index'))

 

 基本上全部的文件都集中在這裏了。因此這個文件是入口文件,經過不一樣的hash值來調用不一樣的組件,從而讓url的變化和界面的變化相對應。redux

這裏將一個個的介紹react-router屬性的做用。這裏的介紹花的篇幅可能會比較多,由於搞懂了這裏,也就基本搞懂react-router了。

 

一、<Route path="/" component={App}>

這一句是全部路由的父集,也就是最高級的位置。路由裏面的東西爲何能夠換來換去呢。就是在這個組件裏面來切換的;

 

這個app裏面的核心代碼以下: .. /component/app.js           //這裏是./component/app    和  ./render/app.js是兩個不一樣的文件來的 !!!

    return (

        <div className="mp_wrap bui_wrap">
            {/**主屏幕**/}
            <div className="mp_pagebox_home">
                
                {/**這裏面的內容會被子路由給代替**/}
                {this.props.children}

                {/**公共頁腳**/}
                <div className="mp_page_footer">
                     <Footer  />
                </div>
                {/**公共頁腳**/}
            </div>
            {/**主屏幕**/}
        </div>
    )

裏面的 {this.props.children} 這句話是核心。它告訴頁面,它的子集都在這裏展現。因此,每次咱們點擊切換不一樣的url,看到不一樣內容的變化,

實際上是這裏面一直替換來替換去而已。沒有替換掉的就是那個Footer組件,由於那個是頁腳用來導航的:

 

裏面的代碼以下:(代碼被簡化,具體看源碼)

./component/router/publicComponent/footer.js

 1 const Footer = React.createClass({
 2 
 3     render: function() {
 4        
 5         return  (
 6                   <div className="bui_avg_sm_4 bui_ta_c bui_bgc_lgray bui_ptb_6"   >
 7                      {/**使用IndexLink,可讓首頁的連接不會一直處於激活狀態**/}
 8                       <IndexLink  to="/" styles={styles.link}  activeStyle={styles.activeLink}>教程</IndexLink >
 9                       <Link to="/circle" styles={styles.link}  activeStyle={styles.activeLink}>烘培圈</Link>
10                       <Link to="/mall" styles={styles.link}  activeStyle={styles.activeLink}>商城</Link>
11                       <Link to="/my" styles={styles.link}  activeStyle={styles.activeLink}>個人</Link>
12                   </div>
13               );
14 
15     }
16 })

這裏經過reac-router提供的Link來進行路徑的跳轉。

這裏有個注意點:IndexLink,就是默認顯示哪一個連接高亮,否則的話默認的首頁的連接狀態就一直處於高亮狀態。經過style,以及activeStyle來切換高亮時的樣式

 

 

 

二、IndexRoute的做用

想象一下當 URL 爲 / 時,咱們想渲染一個在 App 中的組件。不過在此時,App 的 render 中的this.props.children 仍是 undefined,也就是說裏面是空的。

因此咱們要讓它默認顯示首頁的信息。這種狀況咱們可使用 IndexRoute 來設置一個默認頁面。

 

看什麼的29行代碼:

 <Route path="/" component={App}>
      <IndexRoute component={Index} />  

能夠看看這裏的代碼,讓url沒有連接到其餘路由時,默認顯示Index這個組件裏面的內容



三、路由匹配原理 :

嵌套關係:

中文網的解釋:React Router 使用路由嵌套的概念來讓你定義 view 的嵌套集合,當一個給定的 URL 被調用時,整個集合中(命中的部分)都會被渲染。

嵌套路由被描述成一種樹形結構。React Router 會深度優先遍歷整個理由配置來尋找一個與給定的 URL 相匹配的路由。

 

什麼意思呢。上面的入口文件中,能夠看到,其餘路由都是最外層那個app(也就是這個<Route path="/" component={App}>)的子路由,其餘路由都是嵌套在這裏面。

當url變化是,它裏面的{this.props.children}都會替換,也就是所謂的整個集合的命中部分都會被渲染。

 

路徑語法:

中文網原文:

路由路徑是匹配一個(或一部分)URL 的 一個字符串模式。大部分的路由路徑均可以直接按照字面量理解,除了如下幾個特殊的符號:

  • :paramName – 匹配一段位於 /? 或 # 以後的 URL。 命中的部分將被做爲一個參數
  • () – 在它內部的內容被認爲是可選的
  • * – 匹配任意字符(非貪婪的)直到命中下一個字符或者整個 URL 的末尾,並建立一個 splat 參數
<Route path="/hello/:name"> // 匹配 /hello/michael 和 /hello/ryan <Route path="/hello(/:name)"> // 匹配 /hello, /hello/michael 和 /hello/ryan <Route path="/files/*.*"> // 匹配 /files/hello.jpg 和 /files/path/to/hello.jpg 

若是一個路由使用了相對路徑,那麼完整的路徑將由它的全部祖先節點的路徑和自身指定的相對路徑拼接而成。使用絕對路徑可使路由匹配行爲忽略嵌套關係。

 

聽起來比較頭暈,能夠這樣理解,就是正常的url匹配模式就是一條 斜線+路勁名。好比跳到我的中心  <Route path="/my" component={My}>,若是要傳值:就相似這樣 <Route path="tip/:tipName" component={CircleTip} />

其實就這樣理解就好了。否則會把本身搞的很暈。

 

繼續前面的入口文件 render/app.js

  經過前面的瞭解,咱們的頁面在最開始的url的時候有了一個默認的組件 index,當咱們要跳轉的時候,咱們能夠經過url的不一樣來調用不一樣的組件。

好比我的中心,<Route path="/my" component={My}>,當識別到你的url是/my 時,就調用My這個組件。

 

能夠看下圖:方框內,不一樣路由就把對應的裏面的內容給替換掉。

 

 

子路由下還有子路由的狀況

若是在my這個路徑下,我還有子路由怎麼辦呢?就像點擊個人頁面,點擊頭像,能夠跳轉到我的中心那種。方法以下:

  <Route path="/my" component={My}>
          <IndexRoute component={MyNav} />
          <Route path="userCenter" component={MyUserCenter} />
          <Route path="memberClub" component={MemberClub} />
  </Route>

在my這個路徑下,我還有userCenter,memberClub。好比你點擊頭像,就會跳轉到這樣的url   http://localhost:3200/#/my/userCenter?_k=t18l2p

 

{My} 這個組件的內容以下:

 

var Content= React.createClass({

    render(){
        
        return (
                <div>    
                    {this.props.children}
                </div>
        )
    }
})

module.exports= Content

 

裏面的{this,props.children}也是注意點。用來替換它子組件的內容。能夠這麼理解,只要你是父組件,都有一個 {this.props.children}來裝載替換子組件的內容

 

注意點:

由於/my是父路由,因此它的寫法跟最外層的app那個路由時相似的,因此也要設置一個默認顯示的頁面,也就是IndexRouter。

這裏我就默認顯示MyNav這個組件,否則裏面是什麼都沒有的。這點初學時會常常忘記。切記切記!!!

 

 

路由之間參數的傳參:

爲了演示參數的傳遞,我將一個tab的切換弄成了路由以前的傳值,實際應用中沒有必要。只是爲了演示而已,在./render/app.js的第31行

 <Route path="/type/:typeName" component={Type} />

跳轉到了/type/:typeName這裏,並調用對應的{Type}組件,爲它傳了一個typeName的值,因此咱們在傳值時能夠這樣

 

在跳轉到type時,後面着一個你要傳遞的值。

<Link to="/type/餅乾">
	<p className="icon icon1"></p>
	<p className="bui_ta_c bui_tc_gray">餅乾</p>
</Link>

 

那我要獲取到傳遞的值怎樣作呢,能夠這樣,在{Type}組件中。

const { typeName } = this.props.params

其中params就是參數的意思。這樣咱們就能夠在須要使用參數的地方來使用咱們的參數了。

 

暫時就介紹到這裏了。主要是搞懂了./render/app.js裏面的內容和相對應的一些知識,也就基本搞懂路由了。其餘地方的用法都是相似的。

 

參考連接:

react-router中文網:http://react-guide.github.io/react-router-cn/docs/guides/basics/RouteMatching.html

 

 

備註:再次強調一下個人這個實戰目錄結構很差,如需拿去項目中使用,記得把項目結構建好一點。另外,有誤指出,歡迎指出。多多交流

相關文章
相關標籤/搜索