1.简述
- demo:以前用过原生JS写计算器,这里我想要react来写,并且用数据库记录每次计算公式和结果,并且可发请求获取
- 后台部分:建立数据库后,通过Node.js的express框架写接口操作数据库
- 前端页面:通过react的router控制路由编写,然后通过axios发送请求给后台
- 最终结果http://counter.jianjiacheng.com
2.Express简介和上手
express官方链接,具体的通过对官方文档的学习还是比较容易上手的,这里我就简要说明
2.1新建express项目
webstorm可以直接点击newporject来选择expressApp
2.2项目结构与路由挂载
├── app.js # 应用的主入口
├── bin # 启动脚本
├── node_modules # 依赖的模块
├── package.json # node模块的配置文件
├── public # 静态资源,如css、js等存放的目录
├── routes # 路由规则存放的目录
└── views # 模板文件存放的目录
2.3路由
路由写到routes下面
var express = require('express');
var router = express.Router();
router.get('/list', function(req, res, next) {
//pool.query是数据库的连接池下面会说到
pool.query('SELECT * FROM counter;', function (err, rows, fields) {
if (err) throw err;
console.log(rows)
res.json(
rows
)
})
});
router.post('/add', function(req, res, next) {
console.log(req.body)
//var mysqltl='INSERT INTO counter(id,counter, time) VALUES(\''+req.body.counter+'\','+'now()'+');'
var mysqltl=`INSERT INTO counter(counter, time) VALUES('${req.body.counter}',now());`
console.log(mysqltl)
pool.query(mysqltl, function (err, rows, fields) {
if (err) throw err;
console.log(rows)
res.json(
rows
)
})
});
2.4允许跨域请求设置
在app.js里面添加
app.all('*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Methods', '*');
res.header('Content-Type', 'application/json;charset=utf-8');
next();
});
2.5express对数据库的连接
2.5.1. 通过createConnection直接创建连接,这种方式需要去释放连接,不建议使用
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : '******',
database : 'mytest'//你的数据库名字
})
connection.connect()
2.5.2. 通过连接池连接,这样可以出来高并发的情况,也不用去释放连接
var mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit : 100,//最多处理多少连接次数
host : 'localhost',
user : 'root',
password : '****',
database : 'mytest'
});
2.6运行程序
3.数据库建立,与请求
- 这应该没什么好说明的,根据自己的情况建表就完事了
- 建立好数据库后通过express里面的路由页面那里接受前台发的请求,并且通过sql语句操作数据库
- 这里前台的请求我用的axios发送没有的可以cnpm install axios --save
axios({
method: 'post',
headers:{'Content-type':'application/json'},
url: 'http://localhost:3000/counter/add',
data: {
counter: input+"="+value,
}
}).then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
4.react前台页面的搭建
4.1App.js:通过react的router控制界面路由,没有按照可以cnpm install react-router-dom --save
import React, { Component } from 'react';
import CounterView from './Pages/CounterView/index';
import CounterHistory from './Pages/CounterHistory/index';
import Login from './Pages/Login/index';
import { HashRouter,Router,Route,Switch,Link,BrowserRouter} from 'react-router-dom';
import './App.css';
class App extends Component {
render() {
return (
<div>
<BrowserRouter>
<Switch>
<Route path="/" component={Login} exact/>
<Route path="/counter" component={CounterView} />
<Route path="/counterHistory" component={CounterHistory} />
</Switch>
<ul id="menu">
<li><Link to='/'>Home</Link></li>
<li><Link to='/counter'>Counter</Link></li>
<li><Link to='/counterHistory'>History</Link></li>
</ul>
</BrowserRouter>
</div>
);
}
}
export default App;
4.2写法是通过写一个方便灌入数据的button组件,通过事先定义好的数组去动态生成界面
4.3效果图与核心代码
//counterview
import React, { Component } from 'react';
import MyButton from '../../components/MyButton/index';
import { BUTTON_VALUE} from '../../Utils/Enum';
import styles from './index.less';
import axios from 'axios';
class CounterView extends Component {
constructor(props) {
super(props);
this.state = {
inputValue:"",
};
}
getButtonArr = (value=[]) => {
var ButtonArr=[];
value.forEach((outval)=> {
outval.forEach((inval)=> {
ButtonArr.push({value:inval})
})
})
return ButtonArr;
}
count=()=>{
var input = this.state.inputValue
try{
var value = eval(input).toFixed(2);
const _this=this;
axios({
method: 'post',
headers:{'Content-type':'application/json'},
url: 'http://localhost:3000/counter/add',
data: {
counter: input+"="+value,
}
}).then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
return value;
}catch(err){
alert("表达式错误")
}
}
getValue=(e)=>{
var newInputValue=this.state.inputValue;
var id=e.target.innerText;
if(id !== "clear" && id !== "back" && id !== "equal"&&id!=="sign") {
newInputValue = this.state.inputValue+id;
}
if(id === "=") {
var value = this.count();
newInputValue=value;
}
if(id === "clear") {
newInputValue="";
}
if(id === "back") {
newInputValue = this.state.inputValue.substring(0, this.state.inputValue.length - 1);
}
if(id === "√"){
var value = this.count();
if(value){
newInputValue = Math.sqrt(value);
}else{
newInputValue="";
}
}
this.setState({
inputValue:newInputValue,
})
}
changeValue=(e)=>{
var newInputValue =e.target.value;
console.log(newInputValue)
this.setState({
inputValue:newInputValue,
})
}
render() {
var ButtonArr = this.getButtonArr(BUTTON_VALUE)
return (
<div className="box1" >
<input className="input" type="text" value={this.state.inputValue} onChange={(e)=>this.changeValue(e)}/>
<div onClick={(e)=>this.getValue(e)}>
<MyButton data={ButtonArr} width="50px" height="50px"/>{/*事件委托加载mybutton上无效*/}
</div>
</div>
)
}
}
export default CounterView;
import React, { Component } from 'react';
class MyButton extends Component {
render() {
return (
<div >
{this.props.data.map(data=><button value={data.value} key={data.value} style={{width:this.props.width,height:this.props.height}}>{data.value}</button>)}
</div>
);
}
}
export default MyButton;
import React, { Component } from 'react';
import axios from 'axios';
import moment from 'moment';
import './index.less';
class CounterHistory extends Component {
constructor(props) {
super(props);
this.state = {
data:[],
};
}
componentDidMount() {
this.getdata();
}
getdata=()=>{
const _this=this;
axios.get('http://localhost:3000/counter')
.then(function (response) {
console.log(response)
_this.setState({
data:response.data,
});
})
.catch(function (error) {
console.log(error);
})
}
del=(e)=>{
const _this=this;
const id=e.target.id;
axios({
method: 'post',
headers:{'Content-type':'application/json'},
url: 'http://localhost:3000/counter/del',
data: {
id: id,
}
}).then(function (response) {
_this.getdata();
}).catch(function (error) {
console.log(error);
});
}
changeValue=(e)=>{
}
render() {
var data=this.state.data;
console.log(data)
return (
<div className="box1">
<div className="box">
<div><span className="index">index</span>
<span className="eval">历史计算</span>
<span className="time">计算时间</span>
<span>操作</span>
</div>
{data.map((data,index)=>
<div key={data.time}>
<span className="index">{index+1}</span>
<span className="eval">{data.counter}</span>
<span className="time">{moment(data.time).format('YYYY-MM-DD HH:mm:ss')}</span>
<button id={data.id} onClick={event => this.del(event)}>删除</button>
</div>)}
</div>
</div>
)
}
}
export default CounterHistory;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。