React+Node+Express搭建一个前后端demo

栏目: Node.js · 发布时间: 5年前

内容简介:webstorm可以直接点击newporject来选择expressApp

1.简述

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

2.Express简介和上手

express官方链接 ,具体的通过对官方文档的学习还是比较容易上手的,这里我就简要说明

2.1新建express项目

webstorm可以直接点击newporject来选择expressApp

React+Node+Express搭建一个前后端demo

2.2项目结构与路由挂载

├── app.js # 应用的主入口
├── bin  # 启动脚本
├── node_modules # 依赖的模块
├── package.json # node模块的配置文件
├── public # 静态资源,如css、js等存放的目录
├── routes # 路由规则存放的目录
└── views # 模板文件存放的目录

React+Node+Express搭建一个前后端demo

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运行程序

React+Node+Express搭建一个前后端demo

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;

React+Node+Express搭建一个前后端demo

4.2写法是通过写一个方便灌入数据的button组件,通过事先定义好的数组去动态生成界面

React+Node+Express搭建一个前后端demo

4.3效果图与核心代码

React+Node+Express搭建一个前后端demo React+Node+Express搭建一个前后端demo

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Filter Bubble

The Filter Bubble

Eli Pariser / Penguin Press / 2011-5-12 / GBP 16.45

In December 2009, Google began customizing its search results for each user. Instead of giving you the most broadly popular result, Google now tries to predict what you are most likely to click on. Ac......一起来看看 《The Filter Bubble》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具