TodoList React+NODE連結mysql資料庫完成增刪改查DEMO
阿新 • • 發佈:2018-12-16
遇到的難點:
跨域:原因是通過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] }