【原】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

 

 

备注:再次强调一下个人这个实战目录结构很差,如需拿去项目中使用,记得把项目结构建好一点。另外,有误指出,欢迎指出。多多交流

相关文章
相关标签/搜索