摘要:

  react-router相对于flux和redux来说,比较好容易理解一点和容易入门一点。这个是根据我之前的一个项目,然后我用react+react-router+webpack重新写的。

不过没有全部写完。只写了一部分。不过用来实战已经足够了。

不过由于这个项目我主要是用来学习react-router,所有有些地方没必要用路由的我还是用了。所以如果要拿去用,这点要注意。

还有就是这个demo不是很完善,需要自己去完善一下。尤其是一些目录结构,由于当时没考虑好。所以可以稍加完善

注意点:此demo是根据react-router 1.0版本来写的。之前版本的用法我没有学过,是直接就学这个版本的。所以如果语法上跟各位的有区别的话,那应该是版本不同所导致的。

当然,大家学习的话应该最好也以1.0版本来学,因为1.0版本相对来说是比较新和稳定的。而且抛弃了很多以前旧的语法,所以和以前版本的语法是有点区别的。目前好像正在出2.0了。技术的更新真的不是一般的快啊

为什么要用路由?

个人理解的话,就前端而言,路由还是因为单页面应用时代的带来而衍生出来的。当url发生变化时,路由相应的做出一些相应,从而来保证目前的url和要展示的界面一一对应好。

效果图如下:类似于微商城的一个网页。点击页脚的不同位置,可以切换不同的页面。

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

入口文件: render/app.js

 import React from 'react'
import { render } from 'react-dom'
import { Router, Route, IndexRoute, Link, IndexLink } from 'react-router'
import { createHistory, useBasename } from 'history' import App from '../component/app.js'
import Mall from '../component/routers/mall/mall.js'
import Circle from '../component/routers/circle/circle.js'
import CircleType from '../component/routers/circle/circleType.js'
import My from '../component/routers/my/my.js'
import MyNav from '../component/routers/my/myNav.js'
import MyUserCenter from '../component/routers/my/userCenter.js'
import MemberClub from '../component/routers/my/memberClub.js'
import Index from '../component/routers/index/index.js'
import Type from '../component/routers/index/type.js'
import CircleTip from '../component/routers/circle/circleTip.js'
import CircleSay from '../component/routers/circle/circleSay.js' const history = useBasename(createHistory)({
basename: '/React-Router'
}); {/** {this.props.children} 非常重要**/}
{/** 思考:首页也有其他分路由,怎么配**/ }
render((
<Router>
<Route path="/" component={App}>
<IndexRoute component={Index} /> <Route path="/type/:typeName" component={Type} /> <Route path="/mall" component={Mall}>
<Route path="type/:typeName" component={Type} />
</Route> <Route path="/my" component={My}>
<IndexRoute component={MyNav} />
<Route path="userCenter" component={MyUserCenter} />
<Route path="memberClub" component={MemberClub} />
</Route> <Route path="/circle" component={Circle}>
<IndexRoute component={CircleType} />
<Route path="tip/:tipName" component={CircleTip} />
<Route path="say" component={CircleSay} />
</Route> </Route>
</Router>
), document.getElementById('index'))

基本上所有的文件都集中在这里了。所以这个文件是入口文件,通过不同的hash值来调用不同的组件,从而让url的变化和界面的变化相对应。

这里将一个个的介绍react-router属性的作用。这里的介绍花的篇幅可能会比较多,因为搞懂了这里,也就基本搞懂react-router了。

1、<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

 const Footer = React.createClass({

     render: function() {

         return  (
<div className="bui_avg_sm_4 bui_ta_c bui_bgc_lgray bui_ptb_6" >
{/**使用IndexLink,可以让首页的链接不会一直处于激活状态**/}
<IndexLink to="/" styles={styles.link} activeStyle={styles.activeLink}>教程</IndexLink >
<Link to="/circle" styles={styles.link} activeStyle={styles.activeLink}>烘培圈</Link>
<Link to="/mall" styles={styles.link} activeStyle={styles.activeLink}>商城</Link>
<Link to="/my" styles={styles.link} activeStyle={styles.activeLink}>我的</Link>
</div>
); }
})

这里通过reac-router提供的Link来进行路径的跳转。

这里有个注意点:IndexLink,就是默认显示哪个链接高亮,不然的话默认的首页的链接状态就一直处于高亮状态。通过style,以及activeStyle来切换高亮时的样式

2、IndexRoute的作用

想象一下当 URL 为 / 时,我们想渲染一个在 App 中的组件。不过在此时,App 的 render 中的this.props.children 还是 undefined,也就是说里面是空的。

所以我们要让它默认显示首页的信息。这种情况我们可以使用 IndexRoute 来设置一个默认页面。

看什么的29行代码:

 <Route path="/" component={App}>
<IndexRoute component={Index} /> 可以看看这里的代码,让url没有链接到其他路由时,默认显示Index这个组件里面的内容

3、路由匹配原理 :

嵌套关系:

中文网的解释: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

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

【原】react-router项目实战的更多相关文章

  1. 【腾讯Bugly干货分享】React Native项目实战总结

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/577e16a7640ad7b4682c64a7 “8小时内拼工作,8小时外拼成长 ...

  2. React Native 项目实战-Tamic

    layout: post title: React Native 项目实战 date: 2016-10-18 15:02:29 +0800 comments: true categories: Rea ...

  3. React Native 项目实战 -- DoubanProject

    引言:本文是我研究react-native时写的一个简单的demo,代码里有详细的注释,好废话不多说,直接上代码. 1.项目目录 2.index.android.js /** * index.andr ...

  4. React Native项目实战

    算是学习React Native的一次项目总结吧,目的还是提高自己. 包含的内容: 1>仿"美团"页面的实现; 2>封装项目中和自己常用的一些组件; 3>学习别人 ...

  5. react 项目实战(七)用户编辑与删除

    添加操作列 编辑与删除功能都是针对已存在的某一个用户执行的操作,所以在用户列表中需要再加一个“操作”列来展现[编辑]与[删除]这两个按钮. 修改/src/pages/UserList.js文件,添加方 ...

  6. React项目实战:react-redux-router基本原理

    React相关 React 是一个采用声明式,高效而且灵活的用来构建用户界面的框架. JSX 本质上来讲,JSX 只是为React.createElement(component, props, .. ...

  7. react 项目实战(十)引入AntDesign组件库

    本篇带你使用 AntDesign 组件库为我们的系统换上产品级的UI! 安装组件库 在项目目录下执行:npm i antd@3.3.0 -S 或 yarn add antd 安装组件包 执行:npm ...

  8. react 项目实战(九)登录与身份认证

    SPA的鉴权方式和传统的web应用不同:由于页面的渲染不再依赖服务端,与服务端的交互都通过接口来完成,而REASTful风格的接口提倡无状态(state less),通常不使用cookie和sessi ...

  9. react 项目实战(八)图书管理与自动完成

    图书管理 src / pages / BookAdd.js   // 图书添加页 /** * 图书添加页面 */ import React from 'react'; // 布局组件 import H ...

随机推荐

  1. (转)oracle中用户删除不了,ORA-01940提示 “无法删除当前已连接用户”

    Oracle删除用户的提示无法删除当前已连接用户两种解决方法如下: 1.先锁定用户.然后查询进程号,最后删除对应的进程.在删除对应的用户 SQLalter user XXX account lock; ...

  2. [z]Oracle性能优化-读懂执行计划

    http://blog.csdn.net/lifetragedy/article/details/51320192 Oracle的执行计划   得到执行计划的方式       Autotrace例子 ...

  3. CodeSmith Merge策略--小白教程

        为了让 自动产生的代码 和 程序员手写的代码 互不干涉, 提出了Merge策略, 包括以下三种 InsertRegion: 只插入(覆盖)到指定 #region区域 InsertClass: ...

  4. 【随笔】Photoshop简单切图

    一.首先准备一张需要切割的图: 二.打开Photoshop,在ps里打开这张图片: 三.在界面的左边选择切片工具: 四.根据需要,鼠标点住上方和左边的标尺拖动,给图片加上分割辅助线: 五.用切片工具点 ...

  5. jvm、jre、jdk

    JVM和JRE浅谈 Java运行时环境JRE包含:Java虚拟机.库函数.运行Java应用程序和Applet所必须的文件,JDK(又称SDK)包含:JRE的超集.编译器.调试器等开发工具. java平 ...

  6. U盘启动盘 安装双系统 详细教程

    U盘启动盘 安装win7+linux双系统 最近在看鸟哥的linux 私房菜 ,看到多重系统那部分,自然的安装多重系统的激情由此而燃.在网上看了很多资料,感觉都不全.经过艰辛的摸索,终于被我发现了一个 ...

  7. [转载]centos7 快速安装 mariadb(mysql)

    http://blog.csdn.net/default7/article/details/41973887 从最新版本的linux系统开始,默认的是 Mariadb而不是mysql! yum ins ...

  8. 数据库(SQL SERVER)常用知识点

    1,连接数据库字符串 Data Source=192.168.1.249;Initial Catalog=bbx_uf_jiekou;User ID=sa;Password=123 Data Sour ...

  9. Google Chrome 调试

    [原文地址:http://www.cnblogs.com/QLeelulu/archive/2011/08/28/2156402.html ] 在Google Chrome浏览器出来之前,我一直使用F ...

  10. 【洛谷P1196】银河英雄传说

    有特殊意义的一道题-- 加权并查集,我们增加cnt.deep数组 分别表示i点所在链共有多少个点,以及路径压缩之前点i在链中的深度 每次合并时直接修改cnt,路径压缩的同时更新deep 因为每次查询之 ...