TodoList React+NODE链接mysql数据库完成增删改查DEMO

遇到的难点:

跨域:原因是通过gulp启动的React项目等于是从本地路径访问网路的NODE于是会造成跨域问题

解决:在后面加上了跨域访问设置

 res.writeHead(200, {'Content-Type': 'text/plain; charset=utf8','Access-Control-Allow-Origin':"*"});

TodoList

var React = require("react");
var ReactDOM = require("react-dom");
// var mysql = require('mysql');
var axios = require("axios")

// var connection = mysql.createConnection({
//   host     : 'localhost',
//   user     : 'root',
//   password : '1234',
//   database : 'goods'
// });
// connection.connect();
// var conn = new Promise(resolve=>{
// 	connection.query('SELECT * from goods', function (error, results, fields) {
// 		if (error) throw error;
// 		console.log('The solution is: ', results);
// 		resolve(results);
// 	});
// })

/*这只是子组件*/
/*这个是设置的自动增长ID*/
var ids=0;
class todolist extends React.Component{
	constructor(){
		super();
		this.state={
			/*存储任务的数组*/
			arr:[],
			/*完成任务数的记录变量*/
			wancheng:0,
			/*未完成。。。*/
			weiwan:0,
			/*span样式名的记录变量*/
			className12:"todolist_li",
		}

	}
	//find
	find(){
		axios.get("http://192.168.1.104:8080/find").then(
			value=>{
				// alert("success");
				// console.log(value);
				this.state.arr=value.data;
				this.state.weiwan=value.data.length;
				this.setState(this.state);
			}
			,error=>{console.log(error)});
		// axios.get("http://192.168.1.104:8080/findLIST").then(
		// 	value=>{
		// 		// console.log(value.data)
		// 		this.state.arr=value.data;
		// 		// this.state.arr.forEach(function(item){
		// 		// 	item.completed=false;
		// 		// })
		// 		this.state.weiwan=value.data.length;
		// 		this.setState(this.state);
		// 	}
		// 	,error=>{console.log("error")});
	}
	//delete
	delete(id){
		//http://192.168.1.104:8080/delete
		let self = this;
		axios.get("http://192.168.1.104:8080/delete",{params:{id:id}}).then(
			value=>{
				// console.log("success")
				self.find();
			}
			,error=>{console.log("error")});
	}
	//update
	update(item){
		axios.get("http://192.168.1.104:8080/update",{params:{id:item.id,completed:item.completed,title:item.title,bol:item.bol}}).then(
			value=>{
				this.find();
			}
			,error=>{console.log("error")});
	}
	//add
	add(title){
		axios.get("http://192.168.1.104:8080/add",{params:{title:title}}).then(
			value=>{
				this.find();
			}
			,error=>{console.log("error")});
	}
	componentDidMount(){
		// conn.then(value=>{alert("success")})
		this.find();
	}
	/*增加任务的方法,有父组件index.jsx用refs调用传值val*/
	/*val是input任务输入框的value*/
	onAdd(val){
		// this.state.arr.push({title:val,completed:false,id:ids++,bol:true})
		this.add(val);
		this.setState(this.state);
		this.state.zongshu=(this.state.arr).length;
		this.state.weiwan=this.state.zongshu-this.state.wancheng
	}
	/*checkbox的触发事件,该事件把标记完成是否的completed属性反转*/
	onCheck(event){
		/*首先获取CheckBox的value值也就是index数组下标*/
		let index = event.target.value;
		/*把标记取反,用来改变记录,等下用来标记span的样式*/
		this.state.arr[index].completed=!(this.state.arr[index].completed);
		// this.update(this.state.arr[index]);
		this.setState(this.state);
		// console.log(this.state.arr)
		/*记录未完成和完成的个数*/
		/*假如是完成了的*/
		if(this.state.arr[index].completed){
			/*那它的完成数就在基础上加一*/
			this.state.wancheng=this.state.wancheng+1;
			/*任务总数减完成数=未完成数*/
			this.state.weiwan=this.state.arr.length-this.state.wancheng
		}else{
			/*反之,假如已将被选为完成,那么就标记为未完成*/
			/*重新记录未完成个数*/
			this.state.wancheng=this.state.wancheng-1;
			this.state.weiwan=this.state.arr.length-this.state.wancheng
		}
		/*更新该数据,它会自动调用render方法重新把值渲染到视图*/
		this.setState(this.state)
	}
	/*删除任务方法*/
	deleteVal(){
		/*把原来的方法备份*/
		let arr = this.state.arr;
		/*从屁股删起删除*/
		for(let i=arr.length-1;i>=0;i--){
			/*假如标记为true,代表已完成,就干掉他*/
			if (arr[i].completed) {
				/*splice删除方法,第一个参数是从第几位开始删,删几条*/
				// this.state.arr.splice(i,1);
				//后台数据库
				this.delete(this.state.arr[i].id);
			}
			/*把完成的任务数归零*/
			this.state.wancheng=0;
			/*重新计算未完成数*/
			this.state.weiwan=this.state.arr.length-this.state.wancheng
		}
		/*视图重新渲染*/
		this.setState(this.state)
	}

	/*转换显示span和输入input的方法*/
	onInput(event){
		/*触发该方法,可以通过以下的方法获取到DOM对象本体obj*/
		event = event ? event : window.event;
		var obj = event.srcElement ? event.srcElement : event.target;
		//这时obj就是触发事件的对象,可以使用它的各个属性
		//还可以将obj转换成jquery对象,方便选用其他元素
		/*这个obj就是触发方法的span或者input*/
		/*然后获取它的同级上一个元素,就是checkbox DOM节点,该节点记录了该list的index下标*/
		let index = obj.previousSibling.value
		/*获取该下表的bol标记,并取反*/
		let bol = !(this.state.arr[index].bol);
		/*重新设置该属性为原来的反值*/
		this.state.arr[index].bol=bol;
		console.log(obj.nodeName);
		if (obj.nodeName=='INPUT') {
			this.update(this.state.arr[index]);
		}

		/*重新渲染*/
		this.setState(this.state)
		// console.log(this.state.arr[index].bol);
	}
	/*这个方法是让改变后的input可以以改变item.title的值调用的是onChange方法*/
	onInputChange(event){
		/*同样跟上面一样,获取到该对象,然后获取上一个DOM,然后获取index*/
		event = event ? event : window.event;
		var obj = event.srcElement ? event.srcElement : event.target;
		let index = obj.previousSibling.value
		/*把当前的值赋给原来的title内容*/
		this.state.arr[index].title = event.target.value;
		// this.update(this.state.arr[index]);
		/*重新渲染*/
		this.setState(this.state)
		// console.log(event.target.value)
	}

	/*渲染方法*/
	render(){
		/*存储数组用map循环遍历之后的值*/
		var todos = null;
		/*把arr遍历*/
		todos = this.state.arr.map(
			(item,index)=>{
				/*model是存储返回span和input的变量*/
				let model;
				/*如果他的值为true就返回span,否则返回input*/
				if(item.bol){
					/*这里span引用了三元表达式,根据completed属性来判断给文字加上什么样式*/
					model = <span onClick={this.onInput.bind(this)} className={(item.completed)?"change":"sapn1"}>{item.title}</span>
				}else{ 
					model = <input onBlur={this.onInput.bind(this)} onChange={this.onInputChange.bind(this)} type="text" value={item.title}/>
				}

				/*返回渲染后的样式加数据*/
				return <li key={item.id}>
				<input  type="checkbox" checked={item.completed?"checked":null} value={index} onChange={this.onCheck.bind(this)}/>
				{model}
				</li>
			}
		)
		/*这个才是渲染的方法*/
		return(
			<div>
			<ul id="ul1" className="todolist_li">
				{todos}
			</ul>
			<p>完成了{this.state.wancheng}个任务,还有{this.state.weiwan}个未完成<span onClick={this.deleteVal.bind(this)}>【完成】</span></p>
			</div>
			)
		todos="";
	}
}

module.exports = todolist;

NODE.JS

var http = require("http");
var url = require("url");
var mysql      = require('mysql');
var querystring = require('querystring');




var http = require("http");
var url = require("url");
var mysql      = require('mysql');
var querystring = require('querystring');
const express = require('express')
const Router = express.Router()


var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'root',
  password : '1234',
  database : 'goods'
});
connection.connect();

var find = () => new Promise(resolve=>{
  connection.query('SELECT * from todolist', function (error, results, fields) {
    if (error) throw error;
    resolve(results);
  });
})
//delete是关键字
var delete1 = (id) => new Promise(resolve=>{
  connection.query('delete from TodoList where id = ?',[id], function (error, results, fields) {
    if (error) throw error;
    resolve(results);
  });
})
var add1 = (title) => new Promise(resolve=>{
  connection.query('INSERT INTO TodoList(title) VALUES(?)',[title], function (error, results, fields) {
    if (error) throw error;
    resolve(results);
  });
})
var update1 = (title,completed,bol,id) => new Promise(resolve=>{
  connection.query('update TodoList set title=?,completed=?,bol=? where id=?',[title,completed,bol,id], function (error, results, fields) {
    if (error) throw error;
    resolve(results);
  });
})


var httpServer = http.createServer(
  function(req,res){
    if (req.url=="/favicon.ico") {return;}//假如访问的路径是网站图片

    res.writeHead(200, {'Content-Type': 'text/plain; charset=utf8','Access-Control-Allow-Origin':"*"});
    let urlString = req.url;
    let url1 = url.parse(urlString,true);
    console.log(url1);
    let loginName = url1.pathname;
    // res.end(loginName);

    if (loginName=='/find') {
      find().then(
        value=>{
          res.end(JSON.stringify(value));
        })
    }//find
    else if(loginName=='/delete'){
      // console.log("delete")
      // console.log(url1.query.id);
      let id = url1.query.id;
      delete1(id).then(
        value=>{
          res.end(value+"");
        })
    }//delete
    else if(loginName=='/add'){
      let title = url1.query.title;
      add1(title).then(
        value=>{
          res.end(value+"");
        })
    }//add
    else if(loginName=='/update'){
      let title = url1.query.title;
      let completed = url1.query.completed;
      let bol = url1.query.bol;
      let id = url1.query.id;
      if (completed==0) {
        completed=false;
      }else{
        completed=true;
      }
      if (bol==0) {
        bol=false;
      }else{
        bol=true;
      }
      console.log(title+completed+bol+id)
      update1(title,completed,bol,id).then(
        value=>{
          res.end(value+"");
        })
    }

    
    let userName = url1.query.userName;
    let pass = url1.query.pass;
    
  });

httpServer.listen(8080,"192.168.1.104");



// 解析后的路径对象
// Url {
//   protocol: null,
//   slashes: null,
//   auth: null,
//   host: null,
//   port: null,
//   hostname: null,
//   hash: null,
//   search: '?userName=jin&pass=123',
//   query: { userName: 'jin', pass: '123' },
//   pathname: '/login',
//   path: '/login?userName=jin&pass=123',
//   href: '/login?userName=jin&pass=123' }
// { Url: [Function: Url],
//   parse: [Function: urlParse],
//   resolve: [Function: urlResolve],
//   resolveObject: [Function: urlResolveObject],
//   format: [Function: urlFormat],
//   URL: [Function: URL],
//   URLSearchParams: [Function: URLSearchParams],
//   domainToASCII: [Function: domainToASCII],
//   domainToUnicode: [Function: domainToUnicode] }

猜你喜欢

转载自blog.csdn.net/jinqianwang/article/details/83212928