遇到的难点:
跨域:原因是通过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] }