1.简述

  • demo:以前用过原生JS写计算器,这里我想要react来写,并且用数据库记录每次计算公式和结果,并且可发请求获取
  • 后台部分:建立数据库后,通过Node.js的express框架写接口操作数据库
  • 前端页面:通过react的router控制路由编写,然后通过axios发送请求给后台

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.数据库建立,与请求

  1. 这应该没什么好说明的,根据自己的情况建表就完事了
  2. 建立好数据库后通过express里面的路由页面那里接受前台发的请求,并且通过sql语句操作数据库
  3. 这里前台的请求我用的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效果图与核心代码

//counterviewimport 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;