react路由案例(非常适合入门)
前面已经已经讲过一次路由 稍微有些复杂 考虑到有些同学刚接触到 我准备了一个简单的demo 就当自己也顺便复习一下
data.js
1 const data = [ 2 { 3 name: 'Tacos', 4 description: 'A taco (/ˈtækoʊ/ or /ˈtɑːkoʊ/) is a traditional Mexican dish composed of a corn or wheat tortilla folded or rolled around a filling. A taco can be made with a variety of fillings, including beef, pork, chicken, seafood, vegetables and cheese, allowing for great versatility and variety. A taco is generally eaten without utensils and is often accompanied by garnishes such as salsa, avocado or guacamole, cilantro (coriander), tomatoes, minced meat, onions and lettuce.', 5 items: [ 6 { name: 'Carne Asada', price: 7 }, 7 { name: 'Pollo', price: 6 }, 8 { name: 'Carnitas', price: 6 } 9 ] 10 }, 11 { 12 name: 'Burgers', 13 description: 'A hamburger (also called a beef burger, hamburger sandwich, burger or hamburg) is a sandwich consisting of one or more cooked patties of ground meat, usually beef, placed inside a sliced bun. Hamburgers are often served with lettuce, bacon, tomato, onion, pickles, cheese and condiments such as mustard, mayonnaise, ketchup, relish, and green chile.', 14 items: [ 15 { name: 'Buffalo Bleu', price: 8 }, 16 { name: 'Bacon', price: 8 }, 17 { name: 'Mushroom and Swiss', price: 6 } 18 ] 19 }, 20 { 21 name: 'Drinks', 22 description: 'Drinks, or beverages, are liquids intended for human consumption. In addition to basic needs, beverages form part of the culture of human society. Although all beverages, including juice, soft drinks, and carbonated drinks, have some form of water in them, water itself is often not classified as a beverage, and the word beverage has been recurrently defined as not referring to water.', 23 items: [ 24 { name: 'Lemonade', price: 3 }, 25 { name: 'Root Beer', price: 4 }, 26 { name: 'Iron Port', price: 5 } 27 ] 28 } 29 ] 30 31 const dataMap = data.reduce((map,category) => //重点看这里 在干嘛 对es6很有帮助哟 32 { 33 category.itemMap = 34 category.items.reduce((itemMap,item)=>{ 35 itemMap[item.name] = item; 36 return itemMap 37 },{}) 38 map[category.name] = category; 39 return map 40 }, 41 {} 42 ) 43 44 exports.getAll = function () { 45 return data 46 } 47 48 exports.lookupCategory = function (name) { 49 return dataMap[name] 50 } 51 52 exports.lookupItem = function (category, item) { 53 return dataMap[category].itemsMap[item] 54 }
app.js
1 import React from 'react' 2 import { render } from 'react-dom' 3 import { browserHistory, Router, Route, Link } from 'react-router' 4 5 import withExampleBasename from '../withExampleBasename' 6 import data from './data' 7 8 import './app.css' 9 10 const category = ({children,params})=>{ 11 const category = data.lookupCategory(params.category) 12 13 return ( 14 <div> 15 <h1>{category.name}</h1> 16 {children || ( 17 <p>{category.description}</p> 18 )} 19 </div> 20 ) 21 } 22 23 const CategorySidebar = ({ params }) => { 24 const category = data.lookupCategory(params.category) 25 26 return ( 27 <div> 28 <Link to="/">◀︎ Back</Link> // "/" 根目录 到app组件 app包含什么 往下看 29 <h2>{category.name} Items</h2> 30 <ul> 31 {category.items.map((item, index) => ( 32 <li key={index}> 33 <Link to={`/category/${category.name}/${item.name}`}>{item.name}</Link> //见下面的route 34 </li> 35 ))} 36 </ul> 37 </div> 38 ) 39 } 40 41 const Item = ({ params: { category, item } }) => { 42 const menuItem = data.lookupItem(category, item) 43 44 return ( 45 <div> 46 <h1>{menuItem.name}</h1> 47 <p>${menuItem.price}</p> 48 </div> 49 ) 50 } 51 52 const Index = () => ( 53 <div> 54 <h1>Sidebar</h1> 55 <p> 56 Routes can have multiple components, so that all portions of your UI 57 can participate in the routing. 58 </p> 59 </div> 60 ) 61 62 const IndexSidebar = () => ( 63 <div> 64 <h2>Categories</h2> 65 <ul> 66 {data.getAll().map((category, index) => ( 67 <li key={index}> 68 <Link to={`/category/${category.name}`}>{category.name}</Link> 69 </li> 70 ))} 71 </ul> 72 </div> 73 ) 74 75 const App = ({ content, sidebar }) => ( 76 <div> 77 <div className="Sidebar"> 78 {sidebar || <IndexSidebar />} 79 </div> 80 <div className="Content"> 81 {content || <Index />} 82 </div> 83 </div> 84 ) 85 86 render(( 87 <Router history={withExampleBasename(browserHistory, __dirname)}> 88 <Route path="/" component={App}> 89 <Route path="category/:category" components={{ content: Category, sidebar: CategorySidebar }}> // 一级 90 <Route path=":item" component={Item} /> //二级 91 </Route> 92 </Route> 93 </Router> 94 ), document.getElementById('example')) 95
看懂了吧 很简单吧
我们再来看一个例子
1 import React from 'react' 2 import { render } from 'react-dom' 3 import { browserHistory, Router, Route, Link } from 'react-router' 4 5 import withExampleBasename from '../withExampleBasename' 6 7 const User = ({ params: { userID }, location: { query } }) => { 8 let age = query && query.showAge ? '33' : '' 9 10 return ( 11 <div className="User"> 12 <h1>User id: {userID}</h1> 13 {age} 14 </div> 15 ) 16 } 17 18 const App = ({ children }) => ( 19 <div> 20 <ul> 21 <li><Link to="/user/bob" activeClassName="active">Bob</Link></li> 22 <li><Link to={{ pathname: '/user/bob', query: { showAge: true } }} activeClassName="active">Bob With Query Params</Link></li> 23 <li><Link to="/user/sally" activeClassName="active">Sally</Link></li> 24 </ul> 25 {children} 26 </div> 27 ) 28 29 render(( 30 <Router history={withExampleBasename(browserHistory, __dirname)}> 31 <Route path="/" component={App}> 32 <Route path="user/:userID" component={User} /> 33 </Route> 34 </Router> 35 ), document.getElementById('example'))
简单吧 找到自信了吗 。。。
最后看一个复杂一点的 当做巩固吧
一个一个来
1 import React from 'react' 2 import { render } from 'react-dom' 3 import { browserHistory, Router, Route, IndexRoute, Link } from 'react-router' 4 5 import withExampleBasename from '../withExampleBasename' 6 7 const PICTURES = [ 8 { id: 0, src: 'http://placekitten.com/601/601' }, 9 { id: 1, src: 'http://placekitten.com/610/610' }, 10 { id: 2, src: 'http://placekitten.com/620/620' } 11 ] 12 13 const Modal = React.createClass({ 14 styles: { 15 position: 'fixed', 16 top: '20%', 17 right: '20%', 18 bottom: '20%', 19 left: '20%', 20 padding: 20, 21 boxShadow: '0px 0px 150px 130px rgba(0, 0, 0, 0.5)', 22 overflow: 'auto', 23 background: '#fff' 24 }, 25 26 render() { 27 return ( 28 <div style={this.styles}> 29 <p><Link to={this.props.returnTo}>Back</Link></p> //这里是要返回当前属性的地址 30 {this.props.children} 31 </div> 32 ) 33 } 34 })
1 const App = React.createClass({ 2 3 componentWillReceiveProps(nextProps) { //组件改变时 就是路由切换时 4 // if we changed routes... 5 if (( 6 nextProps.location.key !== this.props.location.key && //经过上面的讲解这里的location.key和state 懂吧 7 nextProps.location.state && 8 nextProps.location.state.modal 9 )) { 10 // save the old children (just like animation) 11 this.previousChildren = this.props.children 12 } 13 }, 14 15 render() { 16 let { location } = this.props 17 18 let isModal = ( 19 location.state && 20 location.state.modal && 21 this.previousChildren 22 ) 23 24 return ( 25 <div> 26 <h1>Pinterest Style Routes</h1> 27 28 <div> 29 {isModal ? 30 this.previousChildren : 31 this.props.children 32 } 33 34 {isModal && ( 35 <Modal isOpen={true} returnTo={location.state.returnTo}> // 这里是往回跳转 36 {this.props.children} //大家要问this,props.children 是指的什么 37 </Modal> 38 )} 39 </div> 40 </div> 41 ) 42 } 43 })
index-route 当app没有定义时 被包含进去
1 const Index = React.createClass({ 2 render() { 3 return ( 4 <div> 5 <p> 6 The url `/pictures/:id` can be rendered anywhere in the app as a modal. 7 Simply put `modal: true` in the location descriptor of the `to` prop. 8 </p> 9 10 <p> 11 Click on an item and see its rendered as a modal, then copy/paste the 12 url into a different browser window (with a different session, like 13 Chrome -> Firefox), and see that the image does not render inside the 14 overlay. One URL, two session dependent screens :D 15 </p> 16 17 <div> 18 {PICTURES.map(picture => ( 19 <Link 20 key={picture.id} 21 to={{ 22 pathname: `/pictures/${picture.id}`, 23 state: { modal: true, returnTo: this.props.location.pathname } 24 }} 25 > 26 <img style={{ margin: 10 }} src={picture.src} height="100" /> 27 </Link> 28 ))} 29 </div> 30 31 <p><Link to="/some/123/deep/456/route">Go to some deep route</Link></p> 32 33 </div> 34 ) 35 } 36 })
大家如果还是不很懂 可以看一下index-route 举个例子
1 import React from 'react' 2 import { render } from 'react-dom' 3 import { Router, Route, hashHistory, IndexRoute } from 'react-router' 4 import App from './modules/App' 5 import About from './modules/About' 6 import Repos from './modules/Repos' 7 import Repo from './modules/Repo' 8 import Home from './modules/Home' 9 10 render(( 11 <Router history={hashHistory}> 12 <Route path="/" component={App}> 13 <IndexRoute component={Home}/> 14 <Route path="/repos" component={Repos}> 15 <Route path="/repos/:userName/:repoName" component={Repo}/> 16 </Route> 17 <Route path="/about" component={About}/> 18 </Route> 19 </Router> 20 ), document.getElementById('app'))
看下app.js
1 import React from 'react' 2 import NavLink from './NavLink' 3 4 export default React.createClass({ 5 render() { 6 return ( 7 <div> 8 <h1>React Router Tutorial</h1> 9 <ul role="nav"> 10 <li><NavLink to="/about">About</NavLink></li> 11 <li><NavLink to="/repos">Repos</NavLink></li> 12 </ul> 13 {this.props.children} //如果一开始访问 根目录/ 其他的字组件还没包含进去 那么。。。 看下面 14 </div> 15 ) 16 } 17 })
home.js
1 import React from 'react' 2 3 export default React.createClass({ 4 render() { 5 return <div>Home</div> //知道了吧 刚才进去 被包含进去的就是home组件 当进行路由跳转的时候 6 } 7 })
navLink.js
1 // modules/NavLink.js 2 import React from 'react' 3 import { Link } from 'react-router' 4 5 export default React.createClass({ 6 render() { 7 return <Link {...this.props} activeClassName="active"/> 8 } 9 })
repo.js
1 import React from 'react' 2 3 export default React.createClass({ 4 render() { 5 return ( 6 <div> 7 <h2>{this.props.params.repoName}</h2> 8 </div> 9 ) 10 } 11 })
repos.js
1 import React from 'react' 2 import NavLink from './NavLink' 3 4 export default React.createClass({ 5 render() { 6 return ( 7 <div> 8 <h2>Repos</h2> 9 <ul> 10 <li><NavLink to="/repos/reactjs/react-router">React Router</NavLink></li> 11 <li><NavLink to="/repos/facebook/react">React</NavLink></li> 12 </ul> 13 {this.props.children} //repos肯定有子路由 14 </div> 15 ) 16 } 17 })
无关紧要的about.js
1 import React from 'react' 2 3 export default React.createClass({ 4 render() { 5 return <div>About</div> 6 } 7 })
最重要的index.js
1 import React from 'react' 2 import { render } from 'react-dom' 3 import { Router, Route, hashHistory, IndexRoute } from 'react-router' 4 import App from './modules/App' 5 import About from './modules/About' 6 import Repos from './modules/Repos' 7 import Repo from './modules/Repo' 8 import Home from './modules/Home' 9 10 render(( 11 <Router history={hashHistory}> 12 <Route path="/" component={App}> 13 <IndexRoute component={Home}/> 14 <Route path="/repos" component={Repos}> 15 <Route path="/repos/:userName/:repoName" component={Repo}/> 16 </Route> 17 <Route path="/about" component={About}/> 18 </Route> 19 </Router> 20 ), document.getElementById('app'))
我们来整理一下
1.进入根目录/ 渲染app 下面有home 和 repos(下面又有repo)
2.根据指定路径到不同组件 上面代码中,用户访问/repos
时,会先加载App
组件,然后在它的内部再加载Repos
组件。
今天就这么多 这些基础的东西还是很重要的 话说我最近还真是忙呀
一个屁点大的公司,就我一个前端,还tm什么都要会,静态页面lz一个人些,还要做交互的特效,坑爹的事各种响应式,还非要什么flex布局。。。这还没完呀
而且搞完了lz还要去用redux开发后台页面,现在小公司没一个不坑的,借口都是培养成全站式程序员,但又没实际的培训的技术指导,总监和pm什么的都在家
遥控指挥,你觉得这不是笑话么。。。笑话归笑话,又要开始烧脑了