Node.js小项目——学生信息管理系统
这是迄今为止第一次接触后端的东西,是一个很小的项目,但是对于前端学习入门很好。我是先学了VUE框架再学的Node,学起来比较轻松,不过每个人都有自己的学习方法❤️
一、项目描述
学生信息管理系统,可以实现对信息的增、删、改、查。
二、使用技术
客户端:BootStrap3完成页面的基本框架;JavaScript操作DOM元素
服务端:使用Express框架创建web服务端;利用路由模块完成不同页面对服务端的请求;利用第三方包body-parser获取post请求的参数;利用express-art-template模板引擎完成服务端数据对页面的渲染
这个项目里面没有用数据库,数据存放在json文件中,不用现成的API更适合学习
三、开发步骤
1、建立一个express项目
1. 创建一个文件夹
2. `npm init`设置package.json文件
3. `npm i express -S`安装express包
4. 设置一个入口文件app.js
2、在app.js中编写服务端代码
// 1. 引包
var express = require('express')
// 2. 创建服务器应用程序
var app = express()
// 4.配置静态开放资源
app.use('/public/', express.static('./public/'))
app.use('/static/', express.static('./static/'))
// 3. 端口监听
app.listen(3000, function () {
console.log('app is running at port 3000.')
})
3、BootStrap框架搭建页面
官方文档https://www.bootcss.com/
⭕注意:利用npm安装BootStrap框架的版本和npm的版本有关系,我的npm版本默认安装BootStrap4,但是做项目的时候没有注意到这一点,直接用的是BootStrap3中的样式。。。。找了好多可能出问题的地方,最后发现是版本的原因,哇🥺好气
4、配置模板引擎
npm i -S art-template express-art-template
app.engine('html', require('express-art-template')); //在app.js中编写
模板引擎的使用
服务端:
res.render('html模板名', {模板数据}); //默认会从view文件夹下面找render
客户端:
{{ each students }}
<tr>
<td>{{ $value.number }}</td>
<td>{{ $value.name }}</td>
<td>{{ $value.gender}}</td>
<td>{{ $value.age }}</td>
<td>{{ $value.academy }}</td>
<td>{{ $value.time }}</td>
<td>
<a href="/students/edit?id={{ $value.id }}">编辑</a>
<a href="/students/delete?id={{ $value.id }}">删除</a>
</td>
</tr>
{{ /each }}
或者
`<input value="{{stuId.academy}}" class="form-control" type="text" id="" name="academy" required min="1" max="150">`
4、路由设计
5、配置body-parser获取post请求数据
//1、安装:
npm install --save body-parser
//2、引包:
var bodyParser = require('body-parser')
//3.配置
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
//4、使用:
req.body
6、配置路由及提取路由模块
在项目中新建router.js路由模块,专门用来处理路由相关操作。
新建一个router.js
路由文件:
// 1 创建一个路由容器
var express = require('express');
// 2 把路由都挂载到路由容器中
var router = express.Router();
router.get("/students", function (req, res) {
// 这里面的操作总的分成三步:
// 1、获取表单数据
// 2、[调用student.js中的API]处理数据。
// 3、发送响应
})
router.post("/students/new", function (req, res) {})
....
// 3 把router导出
module.exports = router;
app.js中:
var router = require('./router')
// 把路由容器挂载到 app 服务中
// 这个一定要放在所有配置的最后面
app.use(router)
7.新建student.js处理文件数据
可以让router.js专注于路由功能,便于代码的维护
1、获取数据文件中全部信息 find
2、根据学生id获取学生信息 findById
3、添加新的学生信息到数据文件中 save
4、根据学生id更新数据文件中的内容 updateById
5、根据学生id删除数据文件中的内容 deleteById
⭕因为获取文件信息是异步操作,所以需要回调函数来获取数据
⭕封装API可以先在router.js写怎么调用API,再按照调用需要封装API。体现“上层(调用)决定下层(封装)”的思想
比如:要实现编辑学生信息这个功能,在router.js中对将要封装的API的期待使用如下:
var Student = require('./student');
router.get("/students/edit", function (req, res) {
Student.findById(id, function (err, stuId) {
if (err) {
res.status(500).send("Server error.");
}
res.render('edit.html', {
stuId
})
})
});
所以在student.js中要封装的findById API如下:
/**
* 根据 id 获取学生信息对象
* @param {Number} id 学生 id
* @param {Function} callback 回调函数
*/
exports.findById = function (id, callback) {
fs.readFile(dbPath, 'utf8', function (err, data) {
if (err) return callback(err);
var students = JSON.parse(data).students;
var stuId = students.find(function (item) {
return item.id === parseInt(id);
})
callback(null, stuId);
})
}
8.按照业务功能顺序写代码
- 列表
- 添加
- 编辑
- 删除
9.其它
大框架建起来了,剩下的小细节再扣,比如:
1、客户端性别根据服务端数据来显示,可以采用这种方法 {{ $value.gender == 0 ?"女":"男"}}
2、渲染编辑页面的时候,利用JS完成对性别的渲染
3、之前的数据文件中可以保存相同的数据,我在将数据存到文件之前对其进行了去重操作,想到这一步的时候,突然发现,咦,算法题没白刷,哈哈哈,的确是有用的😊
贴上代码:
// 把对象数据转换为字符串并存到db.json文件中
var saveFile = function (students, callback) {
// 对数组students进行去重操作
for (var i = 0; i < students.length; i++) {
for (var j = i + 1; j < students.length; j++) {
if (students[i].number === students[j].number) {
students.splice(j, 1);
}
}
}
// 把对象数据转换为字符串
var fileData = JSON.stringify({
students
});
// 把新得字符串保存到文件中
fs.writeFile(dbPath, fileData, function (err) {
if (err) {
// 错误就是把错误信息传递给回调函数
return callback(err);
}
// 没有问题就是传递null值
callback(null);
})
}
4、npm5以后的版本安装都不要加--save
参数,它会自动保存依赖信息