小前言
这是一个小小的有关react
的小例子,希望通过一个小例子,可以更好的了解到react、react-router4.0、redux
的集中使用方法。
- 这是基于create-react-app来开发的,一种简单的快速创建
React web
项目的方式是使用 Create React App
工具,相当于一个react
手脚架,此工具由 Facebook
开发并维护。如果你还没有使用过 create-react-app
,你需要先安装。然后就可以通过它创建一个新项目。
- React Router4.0 号称一次学习,随处路由。通过声明式编程模型定义组件,是
React
最强大的核心功能。 React Router
可以为您的应用已声明式的方式定义导航组件最强大的核心功能。 无论是 Web App
的浏览器书签 URLs
,还是 React Native
的导航功能, 只要是可以使用 React
的地方,就可以使用 React Router
。
- Redux 是一个用来管理JavaScript应用中 data-state(数据状态)和UI-state(UI状态)的工具,对于那些随着时间推移状态管理变得越来越复杂的单页面应用(SPAs)它是比较理想。阮老师redux的教程
下面我们看看完成后的小 demo
开始用create-react-app
创建我们的 app
首先 安装好create-react-app
,
npm install -g create-react-app
mac不成功记得用 sudo
然后:
1 2 3
| create-react-app react-plan cd react-plan/ npm start
|
安装会有点慢,耐心等待一下
安装完毕之后,在浏览器地址栏输入localhost:3000
,就可以浏览到刚才创建的 app 啦。如下图
代码开始
创建好应用之后,我们就开始写我们的代码了,在 src
文件夹下面创建一个components
文件夹,并且在这个文件夹下面创建一个home.js
的文件,然后写上我们首页的内容
首页介绍组件
src/components/home.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import React, { Component } from 'react' class Home extends Component { constructor(props) { super(props); } render () { return ( <div> <h2>首页</h2> <p>这是一个 react 学习的基本操作的小栗子</p> <p>通过本次学习可以清楚的掌握, react-router、redux的基本使用方法</p> <br/> <br/> <br/> </div> ) } } export default Home
|
写好了 home.js 之后我们先引入我们的 app 看看
然后在src/App.js
引入我们的 home.js
,App.js就变成了
src/App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import React, { Component } from 'react'; import logo from './logo.svg'; // 引入 homejs import Home from './components/home.js' import './App.css'; class App extends Component { render() { return ( <div className="App"> <div className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h2>Welcome to React</h2> </div> <p className="App-intro"> To get started, edit <code>src/App.js</code> and save to reload. </p> // 使用 home 组件 <Home /> </div> ); } } export default App;
|
写好之后我们就可以成功的写完了home.js
组件啦,是不是很简单,是不是很happy?
一鼓作气,完成所有组件
继续在components
文件夹创建一个plan.js
(计划表)、detail.js
(计划详情)、pupop.js
(添加计划)、的js文件和comment.css
(组件的样式),我们这时候不涉路由的跳转,只要把所有静态的组件先一鼓作气写好来。
tips:这个例子小,为了方便,我把所有的组件样式文件都写到comment.css
里面了,这时候写好的了 css 记得在App.js
里面引入
src/App.js增加一句 import './components/comment.css'
src/components/comment.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
| .main { padding: 10px; flex-direction: row; display: flex; } .NavBox { width: 250px; margin-right: 20px; } .listNav{ text-align: center; } .listNav li { line-height: 40px; } .listNav li a { text-decoration: none; } .listNav li.active{ background: #00a6f7; } .listNav li.active a{ color: #fff; } .side{ width: 100%; } .slist{ font-size: 14px; } .addBtn { font-size: 14px; font-weight: normal; background: skyblue; display: inline-block; padding: 10px; margin-left: 10px; color: #ffffff; border-radius: 4px; cursor: pointer; } .slist li{ padding: 10px; display: flex; flex-direction: row; justify-content: space-between; border-bottom: solid 1px cornflowerblue; } .slist li h3{ font-weight: normal; } .slist li div span{ text-decoration: underline; padding: 0 10px; } .popup{ position: absolute; width: 100%; height: 100%; left: 0; top: 0; background: rgba(0, 0, 0, 0.6); display: flex !important; justify-content: center; align-items: center; } .popup .pbox { width: 50%; height: 320px; background: #ffffff; box-sizing: border-box; padding: 10px; position: relative; } .popup .pbox h4{ font-size: 14px; } .popup .pbox input { margin: 10px 0 20px 0; } .popup .pbox input, .popup .pbox textarea{ display: block; width: 100%; height: 32px; border: 1px solid skyblue; text-indent: 10px; } .popup .pbox textarea { resize: none; height: 100px; margin: 10px 0; } .popup .pbox .close { position: absolute; width: 30px; height: 30px; background: red; text-align: center; line-height: 30px; border-radius: 50%; color: #ffffff; right: -15px; top: -15px; transition: 0.5s; cursor: pointer; } .popup .pbox .close:hover{ transform: rotate(180deg); } .popup .pbox .pBtn { display: flex; justify-content: center; padding-top: 20px; } .popup .pbox .pBtn span{ padding: 10px 20px; background: skyblue; margin: 0 10px; font-size: 14px; color: #ffffff; border-radius: 4px; cursor: pointer; } .plant{ line-height: 50px; position: relative; } .plant p{ position: absolute; right: 0; top: 0; font-size: 14px; background: blue; height: 30px; line-height: 30px; padding: 0 10px; color: #fff; } .planlist{ width: 100%; padding: 10px; border-collapse: collapse; } .planlist td, th{ border: 1px solid blue; line-height: 32px; font-size: 14px; } .plan-delect{ color: red; cursor: pointer; } .plan-delect:hover{ color: blue; text-decoration: underline; } .plan-title{ width: 80%; }
|
计划组件
src/components/plan.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import React, { Component } from 'react' class Plan extends Component { constructor(props) { super(props); } render () { return ( <div> <div className="plant"> <h3>计划表</h3> <p>添加计划</p> </div> <table className="planlist"> <thead> <tr> <th>标题</th> <th>操作</th> </tr> </thead> <tbody> <tr> <td className="plan-title">计划1</td> <td className="plan-delect">删除</td> </tr> </tbody> </table> </div> ) } } export default Plan;
|
测试的时候直接把App.js
刚才写的import Home from './components/home.js'
改成 import Home from './components/plan.js'
,就可以测试plan 组件啦。是不是很简单?下面的同理。
计划详情组件
src/components/detail.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import React, { Component } from 'react' class Detail extends Component { constructor(props) { super(props); } render() { return ( <div style={{padding: '20px'}}> <h3>计划详情</h3> <p>id: 123</p> <p>标题: 测试标题</p> <p>内容: 测试内容</p> </div> ) } } export default Detail
|
添加计划组件
src/components/popup.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| import React, { Component } from 'react' class Pupop extends Component{ constructor (props) { super(props) this.state = { id: '', title: '1', content: '1' } } render() { let self = this; return ( <section className="popup" style={{display: 'block'}}> <div className="pbox"> <span className="close">X</span> <div> <h4>计划标题</h4> <input value={this.state.title} placeholder="请输入计划标题"/> </div> <div> <h4>计划内容</h4> <textarea value={this.state.content} placeholder="请输入计划内容" rows="3"></textarea> </div> <div className="pBtn"> <span>取消</span> <span>确认</span> </div> </div> </section> ) } } export default Pupop
|
呼~~~终于把所有组件都写好了。下面我们就用路由把他们全都串联起来吧。实现点击跳转咯
加入路由
首先记得安装路由 npm install react-router-dom history --save
history这个模块是用来做 js 的跳转,后面我们会介绍到。
安装完成路由模块之后,在src/components/
下面我们在增加一个测试二级路由的文件testrouter.js
,里面的内容很简单,直接把官网的拿进来。
src/components/testrouter.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| import React, { Component } from 'react' import { BrowserRouter as Router, Route, Link } from 'react-router-dom' const Topic = ({ match }) => ( <div> <h3>{match.params.topicId}</h3> </div> ) class TestRouter extends Component { constructor(props) { super(props); console.log(this.props) } render () { return ( <div> <h2>二级路由</h2> <ul> <li> <Link to={`${this.props.match.url}/rendering`}> 使用 React 渲染 </Link> </li> <li> <Link to={`${this.props.match.url}/components`}> 组件 </Link> </li> <li> <Link to={`${this.props.match.url}/props-v-state`}> 属性 v. 状态 </Link> </li> </ul> <Route path={`${this.props.match.url}/:topicId`} component={Topic}/> <Route exact path={this.props.match.url} render={() => ( <h3>请选择一个主题。</h3> )}/> </div> ) } } export default TestRouter
|
然后在App.js做一点改动,引入所有需要的模块,看注释
src/App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| import React, { Component } from 'react' import { BrowserRouter as Router, Route, Link } from 'react-router-dom' import logo from './logo.svg' // 引入4个模块组件 import Plan from './components/plan.js' import Home from './components/home.js' import Popup from './components/popup.js' import TestRouter from './components/testrouter.js' import Detail from './components/detail.js' // 引入样式文件 import './App.css' import './components/comment.css' // 引入路由 import createHistory from 'history/createBrowserHistory' const history = createHistory() // 开始代码 class App extends Component { constructor(props) { super(props); } render() { return ( <div className="App"> <div className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h2 className='App-title'>Welcome to React Plan</h2> </div> <div> // 路由配置 <Router history = {history}> <div className="contentBox"> // 编写导航 <ul className="nav"> <li><Link to="/">首页</Link></li> <li><Link to="/plan">计划表</Link></li> <li><Link to="/test">二级路由</Link></li> </ul> // 路由匹配 <div className="content"> <Route exact path="/" component={Home}/> <Route path="/plan" component={Plan}/> <Route path="/test" component={TestRouter}/> <Route path="/detail/:id" component={Detail}/> </div> </div> </Router> </div> <Popup/> </div> ); } } export default App
|
不是结束的结束:好啦~~~路由也配置好,打开浏览器,在代码正确的情况下,可以愉快的实现跳转咯。之后我们再把 redux 加入进来,这样子就可以,每个组件就可以操作全局的数据了。稍后奉上。react、react-router、redux 也许是最佳小实践2