此文使用React实现简易笔记本,包括环境配置,前台界面和后台应用等内容。其中后台应用主要功能是数据库操作,前台应用的主要功能是显示,增加,删除,更新数据 ,效果如下所示:
一、数据库设计
MongoDB是一个基于分布式文件存储 的数据库,具有高性能、易部署、易使用,存储数据方便等特点。此项目所采用的是Mongodb数据库,集合文件主要包含id,message,timestamps三个字段,其数据文件如下所示:
1、数据结构
javascript
//data.js
//引入mongoose模块
const mongoose = require('mongoose');
//引入schema
const Schema = mongoose.Schema;
//数据结构
const DataSchema = new Schema(
{
id: Number,
message: String
},
{ timestamps: true }
);
//返回schema ,便于通过Node.js使用
module.exports = mongoose.model('Data', DataSchema);
2、注册免费数据库
在浏览器中访问Mongodb官网(MongoDB: The Developer D,如ata Platform | MongoDB),如图所示:
单击如图所示画红线部分,按照提示先进行注册,注册界面如下所示:
注册后出现登录界面如下所示:
登录后按照提示进行操作,注意选择AWS的512MB 自由数据库,并新建访问用户名为guest,完成设置后,如图所示:
单击红色按钮,出现如图所示,使当前MO为右侧512MB自由数据库。
单击黄色按钮,选择第一项,nodejs连接,出现如图所示:
连接代码如上红色所示,连接数据库代码如下:
javascript
//连接数据库
const uri = "mongodb+srv://guest:<guest用户访问密码>@cluster0.gulaw.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0";
mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true });
const db = mongoose.connection;
//检查数据库连接是否成功
db.on('error', console.error.bind(console, 'connection error:'));
//显示连接成功
db.once('open', function() {
console.log('Connected to MongoDB')
})
获取数据代码,如下所示:
javascript
const Data=require('./data');
Data.find().exec()
.then((data) => {
return res.json({ success: true, data: data });
})
.catch((err) => {
return res.json({ success: false, error: err });
})
新增数据代码,如下所示:
javascript
let data = new Data();
const { id, message } = req.body;
if ( (!id && id !==0) || !message) {
return res.json({
success: false,
error: 'INVALID INPUTS'
});
}
data.message = message;
data.id = id;
data.save()
.then(() => res.json({ success: true }))
.catch(err => res.json({ success: false, error: err }));
删除数据数据代码,如下所示:
javascript
const { id } = req.body;
Data.findOneAndDelete(id)
.then(data=>res.json({ success: true }))
.catch(err =>res.json({ success: false, error: err }));
更新数据代码,如下所示:
javascript
const { id, update } = req.body;
Data.findOneAndUpdate({_id: id},update)
.then(data=>{
return res.json({ success: true });
})
.catch(err =>{
return res.json({ success: false, error: err });
});
以上是Mongodb数据库在线使用方法和访问代码,访问数据库采用mongoose库。
二、后台应用
项目后台采用nodejs+express+mongooseb库的方式运行,侦听端口为3000,其中:
'/getData' 为获取数据,访问方式get
'/putData' 为新增数据,访问方式post
'/deleteData' 为删除数据,访问方式delete
'/updateData' 为更新数据,访问方式post
注意:1、采用bodyParser的json编码方式。
2、采用cors库解决访问跨域问题。
3、需安装相应库,其中mongoose为数据库访问库,morgan库为日志库。
后台代码如下所示:
javascript
//定义Mongodb连接
const mongoose=require('mongoose');
//引入express
const express = require('express');
//引入body-parser
const bodyParser = require('body-parser');
//引入morgan
const logger= require('morgan');
const Data=require('./data');
const API_PORT = 3000;
//express实例
const app = express();
const cors = require('cors');
// 允许所有源访问
app.use(cors());
//路由
const router = express.Router();
//使用body-parser
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//开启日志
app.use(logger('dev'));
//连接数据库
/*
const { MongoClient, ServerApiVersion } = require('mongodb');
const uri = "mongodb+srv://guest:qqq123456@cluster0.gulaw.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0";
// Create a MongoClient with a MongoClientOptions object to set the Stable API version
const client = new MongoClient(uri, {
serverApi: {
version: ServerApiVersion.v1,
strict: true,
deprecationErrors: true,
}
});
async function run() {
try {
// Connect the client to the server (optional starting in v4.7)
await client.connect();
// Send a ping to confirm a successful connection
await client.db("admin").command({ ping: 1 });
console.log("Pinged your deployment. You successfully connected to MongoDB!");
} finally {
// Ensures that the client will close when you finish/error
await client.close();
}
}
run().catch(console.dir);
*/
//连接数据库
const uri = "mongodb+srv://guest:qqq123456@cluster0.gulaw.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0";
mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true });
const db = mongoose.connection;
//检查数据库连接是否成功
db.on('error', console.error.bind(console, 'connection error:'));
//显示连接成功
db.once('open', function() {
console.log('Connected to MongoDB')
})
//获取数据的方法
router.get('/getData', (req, res) => {
console.log('/getData已经执行');
Data.find().exec()
.then((data) => {
return res.json({ success: true, data: data });
})
.catch((err) => {
return res.json({ success: false, error: err });
})
});
//添加数据的方法
//用于向数据库添加新的数据
router.post('/putData', (req, res) => {
let data = new Data();
const { id, message } = req.body;
if ( (!id && id !==0) || !message) {
return res.json({
success: false,
error: 'INVALID INPUTS'
});
}
data.message = message;
data.id = id;
data.save()
.then(() => res.json({ success: true }))
.catch(err => res.json({ success: false, error: err }));
})
//数据更新的方法
//用于对数据库已有数据进行更新
router.post('/updateData', (req, res) => {
const { id, update } = req.body;
console.log('updateData已经执行');
console.log(id,update);
Data.findOneAndUpdate({_id: id},update)
.then(data=>{
return res.json({ success: true });
})
.catch(err =>{
return res.json({ success: false, error: err });
});
});
//删除数据的方法
//用于对数据库已有数据进行删除
router.delete('/deleteData', (req, res) => {
const { id } = req.body;
Data.findOneAndDelete(id)
.then(data=>res.json({ success: true }))
.catch(err =>res.json({ success: false, error: err }));
});
//对http请求增加/api路由
app.use('/api', router);
//开启端口
app.listen(API_PORT, () => console.log(`LISTENING ON PORT ${API_PORT}`));
三、前台应用
前台采用React +antd组件方式编写, 整个界面分为四部分,第一部分为List显示笔记内容,第二部分为Card ,包含一个输入框和新增按钮,第三部分为Card ,主要功能是删除笔记,包含一个输入框和删除按钮,第四部分为Card,主要功能是更新笔记,包含两个输入框和更新按钮。前端采用React自带的fetch从服务器中获取笔记,使用axios从服务器中,新增笔记、删除笔记、更新笔记,代码如下所示:
javascript
import React,{ Component } from 'react'
//引入axios用于发送异步请求获取数据
import axios from 'axios'
//引入antd组件库
import { Button ,Input,List,Avatar,Card } from 'antd'
//引入样式库
class App extends Component {
//初始化state
state = {
data: [],
id:0,
message: null,
IntervalIsSet: false,
idToDelete: null,
idToUpdate: null,
objectToUpdate: null
}
//获取数据
getDataFromDb=()=>{
fetch("http://localhost:3000/api/getData")
.then(data=> data.json())
.then(res=>this.setState({data: res.data}))
};
//新增数据
putDataToDB=(message)=>{
let cureentIds=this.state.data.map((data)=>data.id);
let idToBeAdded=0;
while(cureentIds.includes(idToBeAdded)){
idToBeAdded++;
}
axios.post("http://localhost:3000/api/putData",{
id:idToBeAdded,
message:message
})
console.log('message',message);
}
//删除数据
deleteFromDB=(idToDelete)=>{
let objIdToDelete=null;
this.state.data.forEach((data)=>{
if(data.id===idToDelete){
objIdToDelete=data._id;
}
});
axios.delete("http://localhost:3000/api/deleteData",{data:{id:objIdToDelete}});
};
//更新数据
updateDB=(idToUpdate,objectToUpdate)=>{
let objIdToUpdate=null;
this.state.data.forEach((data)=>{
if(data.id==idToUpdate){
objIdToUpdate=data._id;
}
});
axios.post("http://localhost:3000/api/updateData",{
id:objIdToUpdate,
update: {message: objectToUpdate}
});
}
//组件挂载后执行
componentDidMount() {
this.getDataFromDb();
if(!this.state.IntervalIsSet){
let interval=setInterval(this.getDataFromDb,1000);
this.setState({IntervalIsSet: interval});
}
}
//组件卸载前执行
componentWillUnmount() {
if(this.state.IntervalIsSet){
clearInterval(this.state.IntervalIsSet);
this.setState({IntervalIsSet: null});
}
}
//组件更新后执行
render() {
const {data=[]}=this.state;
console.log('data',data);
return (<div style={{width:990,margin:20,backgroundColor:'#ccc'}}>
<List
itemLayout="horizontal"
dataSource={data}
renderItem={item => (
<List.Item>
<List.Item.Meta
avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
title={<span>创建时间:{item.createdAt}</span>}
description={<span>{item.id}:{item.message}</span>}
/>
</List.Item>
)}
/>
<Card
title="新增笔记"
style={{padding: 10,margin: 10}}
>
<Input
placeholder="请输入笔记内容"
style={{width: 200}}
onChange={e=>this.setState({message: e.target.value})}
/>
<Button
type="primary"
style={{margin: 20}}
onClick={()=>this.putDataToDB(this.state.message)}
>新增</Button>
</Card>
<Card
title="删除笔记"
style={{padding: 10,margin: 10}}>
<Input
placeholder="填写所需删除ID"
style={{width: 200}}
onChange={e=>this.setState({idToDelete: e.target.value})}
/>
<Button
type="primary"
style={{margin: 20}}
onClick={()=>this.deleteFromDB(this.state.idToDelete)}
>删除</Button>
</Card>
<Card
title="更新笔记"
style={{padding: 10,margin: 10}}
>
<Input
placeholder="填写所需更新ID"
style={{width: 200,marginRight: 10}}
onChange={e=>this.setState({idToUpdate: e.target.value})}
/>
<Input
placeholder="填写所需更新内容"
style={{width: 200}}
onChange={e=>this.setState({objectToUpdate: e.target.value})}
/>
<Button
type="primary"
style={{margin: 20}}
onClick={()=>this.updateDB(this.state.idToUpdate,this.state.objectToUpdate)}
>更新</Button>
</Card>
</div>
);
}
}
export default App
本文简要讲述了采用mogoose+express+react方式,完成一个简易的笔记本项目,其中在线数据库存由于网络问题,非常不稳定,在调试时需要非常注意,另外,mongoose库访问数据库的代码书写方式新,旧有所不同,跨域访问也应该是在调试时,特别加以留心。