目录结构:
自定义一个包bookMan:
npm init -y
安装所需要的功能模块:
npm install express art-template body-parser express-art-template --save
在index.js文件里面完成主体配置:
导入模块:
const express = require('express');
const template = require('art-template');
const bodyParser = require('body-parser');
const path = require('path');
const app = express();
设置模板引擎:
// 设置模板的路径
app.set('views',path.join(__dirname,'views'));
// 设置模板引擎,定义模板的后缀名
app.set('view engine','art');
// 使express兼容art-template模板引擎
app.engine('art', require('express-art-template'));
处理请求参数:
//处理请求参数
// 挂载参数处理中间件(post)
app.use(bodyParser.urlencoded({ extended: false }));
// 处理json格式的参数
app.use(bodyParser.json());
启动服务器功能:
//启动服务器功能
//配置路由
app.use(router);
//监听端口
app.listen(3000,()=>{
console.log('running...');
});
在router.js文件里面封装一个路由模块:
导入模块:
const express = require('express');
const router = express.Router();
const service = require('./service.js');
路由处理:
//渲染主页
router.get('/',service.showIndex);
//添加图书(跳转到添加图书的页面)
router.get('/toAddBook',service.toAddBook);
//添加图书(提交表单)
router.post('/addBook',service.addBook)
//跳转到编辑图书信息页面
router.get('/toEditBook',service.toEditBook);
// 编辑图书提交表单
router.post('/editBook',service.editBook);
// 删除图书信息
router.get('/deleteBook',service.deleteBook);
导出路由模块,供index.js里面的app.use(router)使用:
module.exports = router;
在service.js文件里面封装一个业务模块:
导入模块:
const path = require('path');
const fs = require('fs');
若将数据存放在json文件里面则还需要导入数据所在的json文件:
把数据放在json文件里面的缺点:每次对数据进行操作都要重新去写文件,当数据量很大的时候,性能的开销会很大
const data = require('./data.json');
封装可以全局调用的两个函数:
自动生成图书编号(自增)的maxBookCode函数:
let maxBookCode = () => {
let arr = [];
data.forEach((item) => {
arr.push(item.id);
});
return Math.max.apply(null,arr);
}
将修改后的data重新写入data.json文件的writeDataToFile函数:
let writeDataToFile = (res) => {
fs.writeFile(path.join(__dirname , 'data.json'), JSON.stringify(data,null,4) , (err) => {
if(err){
res.send('server error');
}
// 文件写入成功之后重新跳转到主页面
res.redirect('/');
})
}
渲染主页面:
exports.showIndex = (req,res) => {
res.render('index',{list : data});
}
此业务主要是为了操作将data.json里面的数据渲染进主页面index.art(是一个需要模板引擎渲染的模板文件):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>图书管理系统</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
<script src="main.js"></script>
<link rel="stylesheet" type="text/css" href="/www/style.css">
</head>
<body>
<div class="title">图书管理系统<a href="/toAddBook">添加图书</a></div>
<div class="content">
<table cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>编号</th>
<th>名称</th>
<th>作者</th>
<th>分类</th>
<th>描述</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{{each list}}
<tr>
<td>{{$value.id}}</td>
<td>{{$value.name}}</td>
<td>{{$value.author}}</td>
<td>{{$value.category}}</td>
<td>{{$value.desc}}</td>
<td><a href="/toEditBook?id={{$value.id}}">修改</a>|<a href="/deleteBook?id={{$value.id}}">删除</a></td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</body>
</html>
添加图书(跳转到添加图书的页面):
exports.toAddBook = (req,res) => {
res.render('addBook',{})
}
此业务主要是为了渲染addBook.art(是一个需要模板引擎渲染的模板文件):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加图书</title>
</head>
<body>
<div>添加图书</div>
<form action="/addBook" method="post">
名称:<input type="text" name="name"><br>
作者:<input type="text" name="author"><br>
分类:<input type="text" name="category"><br>
描述:<input type="text" name="desc"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
添加图书(提交表单):
exports.addBook = (req,res) => {
//获取表单数据
let info = req.body;
let book = {};
for (let key in info){
book[key] = info[key];
}
book.id = maxBookCode() + 1;
data.push(book);
// 把内存中的数据写入文件
writeDataToFile(res);
}
跳转编辑图书页面:
exports.toEditBook = (req,res) => {
let id = req.query.id;
let book = {};
data.forEach((item) => {
if(item.id == id){
book = item;
return;
}
});
// console.log(data);
res.render('editBook',book);
}
此业务主要是为了操作将所选需要修改的项对应的数据渲染进editBook.art(是一个需要模板引擎渲染的模板文件):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>修改图书</title>
</head>
<body>
<div>修改图书</div>
<form action="/editBook" method="post">
<input type="hidden" name="id" value="{{id}}">
名称:<input type="text" name="name" value="{{name}}"><br>
作者:<input type="text" name="author" value="{{author}}"><br>
分类:<input type="text" name="category" value="{{category}}"><br>
描述:<input type="text" name="desc" value="{{desc}}"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
编辑图书(提交表单):
exports.editBook = (req,res) => {
let info = req.body;
// console.log(info);
// console.log(data);
data.forEach((item)=>{
// console.log(item);
if(info.id == item.id){
console.log(info.id);
for(let key in info){
item[key] = info[key];
}
return;
}
});
// 把内存中的数据写入文件
writeDataToFile(res);
}
删除图书信息:
exports.deleteBook = (req,res) => {
let id = req.query.id;
data.forEach((item,index)=>{
if(id == item.id){
// 删除数组的一项数据
data.splice(index,1);
}
return;
});
// 把内存中的数据写入文件
writeDataToFile(res);
}