先看一段代码能否秒懂很重要

这是app.js  全局js的入口

 import React from 'react'
import { render } from 'react-dom'
import { Router, browserHistory } from 'react-router' import withExampleBasename from '../withExampleBasename'
import './stubs/COURSES' const rootRoute = {
childRoutes: [ { //子路由
path: '/',
component: require('./components/App'),
childRoutes: [
require('./routes/Calendar'), //当前目录下有这么几个子路由
require('./routes/Course'),
require('./routes/Grades'),
require('./routes/Messages'),
require('./routes/Profile')
]
} ]
} render((
<Router
history={withExampleBasename(browserHistory, __dirname)}
routes={rootRoute}
/>
), document.getElementById('example'))

以上面的calendar为例子  calendar下面有component 和index.js    同样其他如course  grades等下面也一样

index.js

 module.exports = {
path: 'calendar',
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('./components/Calendar'))
})
}
}

component下面有calendar.js

 import React, { Component } from 'react'

 class Calendar extends Component {
render() {
const events = [
{ id: 0, title: 'essay due' }
] return (
<div>
<h2>Calendar</h2>
<ul>
{events.map(event => (
<li key={event.id}>{event.title}</li>
))}
</ul>
</div>
)
}
} module.exports = Calendar

怎么样找到诀窍了吗   /routes/calendar/index.js +component/calendar.js    /routes/grades/index.js +component/grades.js

找到规律了吧 !!

来一个稍微复杂的路由

(这是全局的变量入口) COURSE.JS

 global.COURSES = [
{
id: 0,
name: 'React Fundamentals',
grade: 'B',
announcements: [
{
id: 0,
title: 'No class tomorrow',
body: 'There is no class tomorrow, please do not show up'
}
],
assignments: [
{
id: 0,
title: 'Build a router',
body: 'It will be easy, seriously, like 2 hours, 100 lines of code, no biggie',
grade: 'N/A'
}
] }, {
id: 1,
name: 'Reusable React Components',
grade: 'A-',
announcements: [
{
id: 0,
title: 'Final exam next wednesday',
body: 'You had better prepare'
}
],
assignments: [
{
id: 0,
title: 'PropTypes',
body: 'They aren\'t for you.',
grade: '80%'
},
{
id: 1,
title: 'Iterating and Cloning Children',
body: 'You can totally do it.',
grade: '95%'
}
]
}
]

Course路由下面有子路由 他的目录结构 /routes/course/index.js +component(course.js+nav.js+dashborad.js)+ routers/(assignments + announcement +grade.js)

瞬间有点凌乱  有木有  往下看就明白了

course.js

 /*globals COURSES:true */
import React, { Component } from 'react'
import Dashboard from './Dashboard'
import Nav from './Nav' const styles = {} styles.sidebar = {
float: 'left',
width: 200,
padding: 20,
borderRight: '1px solid #aaa',
marginRight: 20
} class Course extends Component {
render() {
let { sidebar, main, children, params } = this.props
let course = COURSES[params.courseId] //这是啥? 根据前面导航条转过来的

let content
if (sidebar && main) { //根据条件 初始化组件内容
content = (
<div>
<div className="Sidebar" style={styles.sidebar}>
{sidebar}
</div>
<div className="Main" style={{ padding: 20 }}>
{main}
</div>
</div>
)
} else if (children) {
content = children
} else {
content = <Dashboard /> //走的是这一步
} return (
<div>
<h2>{course.name}</h2>
<Nav course={course} /> //吸进来的一个组件 确定是去哪里 announcement assignment grades
{content}
</div>
)
}
} module.exports = Course

貌似还有点迷糊  继续往下看吧

nav.js

 import React, { Component } from 'react'
import { Link } from 'react-router' const styles = {} styles.nav = {
borderBottom: '1px solid #aaa'
} styles.link = {
display: 'inline-block',
padding: 10,
textDecoration: 'none'
} styles.activeLink = {
...styles.link,
color: 'red'
} class Nav extends Component {
render() {
const { course } = this.props
const pages = [
[ 'announcements', 'Announcements' ],
[ 'assignments', 'Assignments' ],
[ 'grades', 'Grades' ]
] return (
<nav style={styles.nav}>
{pages.map((page, index) => (
<Link
key={page[0]}
activeStyle={index === 0 ? { ...styles.activeLink, paddingLeft: 0 } : styles.activeLink}
style={index === 0 ? { ...styles.link, paddingLeft: 0 } : styles.link}
to={`/course/${course.id}/${page[0]}`} //这里是3个导航的跳转 /course/${course.id}/announcement 去往announcements assignments grades
>{page[1]}</Link>
))}
</nav>
)
}
} export default Nav

来看一下router/announcement(index.js + component + router)    

index.js 文件

 module.exports = {
path: 'announcements',

getChildRoutes(partialNextState, cb) {
require.ensure([], (require) => {
cb(null, [
require('./routes/Announcement') //这又是一个子路由
])
})
}, getComponents(nextState, cb) {
require.ensure([], (require) => {
cb(null, {
sidebar: require('./components/Sidebar'),
main: require('./components/Announcements') //依赖的组件
})
})
}
}

看到这里是否有点明白了  就像洋葱一层一层拨动我的心。。。还没完呢

component/announcement.js

 import React, { Component } from 'react'

 class Announcements extends Component {
render() {
return (
<div>
<h3>Announcements</h3>
{this.props.children || <p>Choose an announcement from the sidebar.</p>} //这个props在哪里找呀
</div>
)
}
} module.exports = Announcements

component/sidebar.js

 import React, { Component } from 'react'
import { Link } from 'react-router' class AnnouncementsSidebar extends Component {
render() {
let { announcements } = COURSES[this.props.params.courseId] //注意这种es6的语法 取得是里面announcements的直

return (
<div>
<h3>Sidebar Assignments</h3>
<ul>
{announcements.map(announcement => (
<li key={announcement.id}>
<Link to={`/course/${this.props.params.courseId}/announcements/${announcement.id}`}>
{announcement.title} //这个到了最后了
</Link>
</li>
))}
</ul>
</div>
)
}
} module.exports = AnnouncementsSidebar

还没完呢  还有个  router-anouncement /index.js + announcement.js 的路由

看index.js 里面的内容

 module.exports = {
path: ':announcementId', //终于真相大白了 !!

getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('./components/Announcement'))
})
}
}

在看最里面的组件announcement.js

 import React, { Component } from 'react'

 class Announcement extends Component {
render() {
let { courseId, announcementId } = this.props.params //这个很关键 怎么着呢 说白了就是 地址的参数 ${courseId} ${announceId}
let { title, body } = COURSES[courseId].announcements[announcementId] return (
<div>
<h4>{title}</h4>
<p>{body}</p>
</div>
)
}
} module.exports = Announcement

我们大概可以看出来  这个路由到底是如何运作了   还有些细节问题我们继续看

整理一下思路 再出发

1. 第一个app.js   确定根目录  /

2. /calendar   /course   /message   /profile   这都是二级目录   下面都有一个  index.js   指定当前的路径  如course/index.js    指定path:course;

3./course/${courseiD}/announcement/${announcementId}    /course/${courseiD}/assignment/${assignmentId}  这是 深层次的

4./course/calendar  course/grades   这是浅层次的

最后是关键的全局组件

app.js

 import React, { Component } from 'react'
import Dashboard from './Dashboard'
import GlobalNav from './GlobalNav' class App extends Component {
render() {
return (
<div>
<GlobalNav />
<div style={{ padding: 20 }}>
{this.props.children || <Dashboard courses={COURSES} />} //如果该属性没有children 就render dashboard
</div>
</div>
)
}
} module.exports = App

dashboard.js

 import React, { Component } from 'react'
import { Link } from 'react-router' class Dashboard extends Component {
render() {
const { courses } = this.props

return (
<div>
<h2>Super Scalable Apps</h2>
<p>
Open the network tab as you navigate. Notice that only the amount of
your app that is required is actually downloaded as you navigate
around. Even the route configuration objects are loaded on the fly.
This way, a new route added deep in your app will not affect the
initial bundle of your application.
</p>
<h2>Courses</h2>{' '}
<ul>
{courses.map(course => (
<li key={course.id}>
<Link to={`/course/${course.id}`}>{course.name}</Link> //这里会根据当前id去不同的course页面
</li>
))}
</ul>
</div>
)
}
} export default Dashboard

globalNav.js  全局导航

 import React, { Component } from 'react'
import { Link } from 'react-router' const dark = 'hsl(200, 20%, 20%)'
const light = '#fff'
const styles = {} styles.wrapper = {
padding: '10px 20px',
overflow: 'hidden',
background: dark,
color: light
} styles.link = {
padding: 11,
color: light,
fontWeight: 200
} styles.activeLink = {
...styles.link,
background: light,
color: dark
} class GlobalNav extends Component { constructor(props, context) {
super(props, context)
this.logOut = this.logOut.bind(this)
} logOut() {
alert('log out')
} render() {
const { user } = this.props

return (
<div style={styles.wrapper}>
<div style={{ float: 'left' }}>
<Link to="/" style={styles.link}>Home</Link>{' '} // 回到根目录
<Link to="/calendar" style={styles.link} activeStyle={styles.activeLink}>Calendar</Link>{' '}
<Link to="/grades" style={styles.link} activeStyle={styles.activeLink}>Grades</Link>{' '}
<Link to="/messages" style={styles.link} activeStyle={styles.activeLink}>Messages</Link>{' '}
</div>
<div style={{ float: 'right' }}>
<Link style={styles.link} to="/profile">{user.name}</Link> <button onClick={this.logOut}>log out</button>
</div>
</div>
)
}
} GlobalNav.defaultProp= {
user: {
id: 1,
name: 'Ryan Florence'
}
} export default GlobalNav

好吧  现在头绪出来了吧    我反正有点眉目了

1.首先是index.html    有个globalnav    /    /calendar   /grades   /message   /profile   分别去向  主页  日历页   年级页   信息页   详情页

2.如果 找不到props.children  就会渲染course   也会根据当前的courseid去往相应页

好吧 今天就这么多   让我好好捋捋。。。

react路由深度解析的更多相关文章

  1. Kafka深度解析

    本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/01/02/Kafka深度解析 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅 ...

  2. VueRouter 源码深度解析

    VueRouter 源码深度解析 该文章内容节选自团队的开源项目 InterviewMap.项目目前内容包含了 JS.网络.浏览器相关.性能优化.安全.框架.Git.数据结构.算法等内容,无论是基础还 ...

  3. Kafka深度解析(如何在producer中指定partition)(转)

    原文链接:Kafka深度解析 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅的消息系统.主要设计目标如下: 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能 ...

  4. React路由-基础篇

    React-Router-DOM ReactRouter网址, 安装 -npmjs找到react-router-dom -yarn add react-router-dom 基本使用方法 1.创建一个 ...

  5. 简单的说一下react路由(逆战班)

    现代前端大多数都是SPA(单页面程序),也就是只有一个HTML页面的应用程序,因为它的用户体验更好,对服务器压力更小,所以更受欢迎,为了有效的使用单个页面来管理原来多页面的功能,前端路由应运而生. 前 ...

  6. 七天接手react项目 系列 —— react 路由

    其他章节请看: 七天接手react项目 系列 react 路由 本篇首先讲解路由原理,接着以一个基础路由示例为起点讲述路由最基础的知识,然后讲解嵌套路由.路由传参,最后讲解路由组件和一般组件的区别,以 ...

  7. ASP.NET路由模型解析

    大家好,我又来吹牛逼了 ~-_-~ 转载请注明出处:来自吹牛逼之<ASP.NET路由模型解析> 背景:很多人知道Asp.Net中路由怎么用的,却不知道路由模型内部的运行原理,今天我就给大家 ...

  8. [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析

    [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析 标签: webkit内核JavaScriptCore 2015-03-26 23:26 2285 ...

  9. 第37课 深度解析QMap与QHash

    1. QMap深度解析 (1)QMap是一个以升序键顺序存储键值对的数据结构 ①QMap原型为 class QMap<K, T>模板 ②QMap中的键值对根据Key进行了排序 ③QMap中 ...

随机推荐

  1. linux awk 一看就懂

    awk是什么 awk是linux环境下的一个命令行工具,但是由于awk强大的能力,我们可以为awk工具传递一个字符串,该字符串的内容类似一种编程语言的语法,我们可以称其为Awk语言,而awk工具本身则 ...

  2. [Xamarin] 動態載入Fragment (转帖)

    這篇我們來動態加入,一樣務求好懂簡單 1.一樣先將專案調整成3.0以上版本 2.首先建立自定Control的Layout \Resources\Layout\MyControlLayout1.axml ...

  3. c# 动态执行脚本,相关的几个脚本引擎.

    Jint   嵌入式的javascript脚本支持引擎,一直都在更新,对各种方法支持也比较好,可以 C# 交互. https://github.com/sebastienros/jint Jurass ...

  4. Spring AOP在函数接口调用性能分析及其日志处理方面的应用

    面向切面编程可以实现在不修改原来代码的情况下,增加我们所需的业务处理逻辑,比如:添加日志.本文AOP实例是基于Aspect Around注解实现的,我们需要在调用API函数的时候,统计函数调用的具体信 ...

  5. [.net 面向对象编程基础] (16) 接口

    [.net 面向对象编程基础] (16) 接口 关于“接口”一词,跟我们平常看到的电脑的硬件“接口”意义上是差不多的.拿一台电脑来说,我们从外面,可以看到他的USB接口,COM接口等,那么这些接口的目 ...

  6. Android Studio 1.0.2项目实战——从一个APP的开发过程认识Android Studio

    Android Studio 1.0.1刚刚发布不久,谷歌紧接着发布了Android Studio 1.0.2版本,和1.0.0一样,是一个Bug修复版本.在上一篇Android Studio 1.0 ...

  7. java线程与并发(一)

    有好几个月没写博客了,各种破事儿忙完,决定继续写博客,恰好最近想了解下有关Java并发的一些知识,所以就准备这一段时间,用零碎的时间多记录一点有关并发的知识.希望这次能一直坚持下去. 想了解并发,必须 ...

  8. jQuery为哪般去掉了浏览器检测

    由于做HTML5相关的项目,许多前卫时髦的前端技术就需要考虑一下IE是否支持.要是在以前,可以很方便地调用jQuery的jQuery.browser来实现. If(jQuery.browser.msi ...

  9. 绝对干货:自定义msi安装包的执行过程

    有时候我们需要在程序中执行另一个程序的安装,这就需要我们去自定义msi安装包的执行过程. 比如我要做一个安装管理程序,可以根据用户的选择安装不同的子产品.当用户选择了三个产品时,如果分别显示这三个产品 ...

  10. 使用aggregate在MongoDB中查找重复的数据记录

    我们知道,MongoDB属于文档型数据库,其存储的文档类型都是JSON对象.正是由于这一特性,我们在Node.js中会经常使用MongoDB进行数据的存取.但由于Node.js是异步执行的,这就导致我 ...