一、项目介绍

①使用nodejs+bootstrap开发

②对文件进行合理的模块化

③实现基本的增删改查功能

二、思路

①处理模块,处理模块,配置开发静态资源,配置模块引擎

②路由设计,提取路由模块

③单独的文件用于封装一些方法:查找学生数据,保存学生数据,更新学生数据,删除学生数据

④单独的路由模块实现具体功能:通过路由接收请求,调用数据操作API处理数据,发送操作结果给客户端

三、功能实现

①目录

②npm安装的包

③代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>管理系统</title>
<link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
<nav class="navbar navbar-expand navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="#">学生管理系统</a>
</nav>
<main class="container mt-5">
<h1 class="alert-heading">学生管理
<a class="btn btn-link btn-sm" href="/students/new">添加学生</a>
</h1>
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>爱好</th>
<th class="text-center" width="140">操作</th>
</tr>
</thead>
<tbody>
{{each students}}
<tr>
<td>{{$value.id}}</td>
<td>{{$value.name}}</td>
<td>{{$value.gender}}</td>
<td>{{$value.age}}</td>
<td>{{$value.hobbies}}</td>
<td>
<a href="/students/edit?id={{$value.id}}">编辑</a>
<a href="/students/delete?id={{$value.id}}">删除</a>
</td>
</tr>
{{/each}}
</tbody>
</table>
<ul class="pagination justify-content-center">
<li class="page-item"><a class="page-link" href="#">&laquo;</a></li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">&raquo;</a></li>
</ul>
</main>
</body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加学生</title>
<link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
<nav class="navbar navbar-expand navbar-dark bg-dark fixed-top">
<a href="#" class="navbar-brand">学生管理系统</a>
</nav>
<main class="container mt-5">
<h1 class="alert-heading">添加学生</h1>
<form action="/students/new" method="post" autocomplete="off">
<div class="form-group">
<label for="name">姓名</label>
<input type="text" name="name" id="name" class="form-control">
</div>
<div class="form-group">
<label for="gender" class="radio-inline">性别</label><br>
<input type="radio" name="gender" value="0" id="gender">男&nbsp;&nbsp;&nbsp;
<input type="radio" name="gender" value="1" id="gender">女
</div>
<div class="form-group">
<label for="age">年龄</label>
<input type="number" name="age" id="age" class="form-control">
</div>
<div class="form-group">
<label for="hobbies">爱好</label>
<input type="text" name="hobbies" id="hobbies" class="form-control">
</div>
<button class="btn btn-primary">保存</button>
</form>
</main>
</body>
</html>

new.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加学生</title>
<link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
<nav class="navbar navbar-expand navbar-dark bg-dark fixed-top">
<a href="#" class="navbar-brand">学生管理系统</a>
</nav>
<main class="container mt-5">
<h1 class="alert-heading">添加学生</h1>
<form action="/students/edit" method="post" autocomplete="off">
<div class="form-group">
<label for="id"></label>
<input type="hidden" name="id" id="id" class="form-control" value="{{student.id}}">
</div>
<div class="form-group">
<label for="name">姓名</label>
<input type="text" name="name" id="name" class="form-control" value="{{student.name}}" >
</div>
<div class="form-group">
<label for="gender" class="radio-inline">性别</label><br>
<input type="radio" name="gender" value="0" id="gender">男&nbsp;&nbsp;&nbsp;
<input type="radio" name="gender" value="1" id="gender">女
</div>
<div class="form-group">
<label for="age">年龄</label>
<input type="number" name="age" id="age" class="form-control" value="{{student.age}}">
</div>
<div class="form-group">
<label for="hobbies">爱好</label>
<input type="text" name="hobbies" id="hobbies" class="form-control" value="{{student.hobbies}}">
</div>
<button class="btn btn-primary">保存</button>
</form>
</main>
</body>
</html>

edit.html

{
"students": [{
"id": 1,
"name": "赵一",
"gender": 0,
"age": 18,
"hobbies": "足球"
}, {
"id": 2,
"name": "孙二",
"gender": 1,
"age": 20,
"hobbies": "篮球"
}, {
"id": 3,
"name": "张三",
"gender": 0,
"age": 30,
"hobbies": "彩票"
}, {
"id": 4,
"name": "李四",
"gender": 1,
"age": 25,
"hobbies": "代码"
}, {
"id": 5,
"name": "王五",
"gender": 0,
"age": 10,
"hobbies": "游戏"
}]
}

db.json

/**
* app.js入口模块:
* 1.创建服务,
* 2.服务相关配置:模板引擎,body-parser配置,静态服务资源,挂载路由
* 3.监听端口启动服务
*/
//npm安装并加载express
var express=require('express');
var app=express();
// 加载路由模块
var router=require('./router');
// npm安装并加载body-parser
var bodyParser=require('body-parser');
//公开node_modules和public目录
app.use('/node_modules/',express.static('./node_modules/'));
app.use('/public/',express.static('./public/'));
// npm安装art-template和express-art-template并配置express-art-template(需要在挂载路由之前)
app.engine('html',require('express-art-template'));
// 配置body-parser(需要在挂载路由之前)
app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());
// 挂载路由
app.use(router);
// 绑定端口
app.listen(3000,function(){
console.log('server is running at port 3000...')
});

app.js

/**
* router.js路由模块:
* 处理路由,根据不同的请求方法或者请求路径设置具体的返回数据
*/
// 加载相关模块
var fs=require('fs');
var express=require('express');
var Student=require('./student');
// 创建一个路由容器
var router=express.Router();
/** 路由设计:
* 请求方法 ==== 请求路径 ==== 参数 =====备注
* GET ==== /students ==== 参数无 ====渲染首页
* GET ==== /students/new ===== 参数无 ======渲染添加学生页面
* POST ==== /students/new ===== 参数name,age,gender,hobbies ======添加学生页面提交表单
* GET ==== /students/edit ===== 参数id ======渲染编辑页面
* POST ==== /students/edit ===== 参数id,name,age,gender,hobbies ======编辑学生页面表单提交
* GET ==== /students/delete ===== 参数id ======处理删除请求
*/
// 处理路由:把路由都挂载到路由容器
router.get('/students',function(req,res){
Student.find(function(err,students){
if(err){
return res.status(500).send('server error')
}
res.render('index.html',{
students:students
})
});
});
router.get('/students/new',function(req,res){
res.render('new.html')
});
router.post('/students/new',function(req,res){
// 获取表单数据-->处理(保存到db.json)-->发送响应
Student.save(req.body,function(err){
if(err){
return res.status(500).send('server error')
}
res.redirect('/students')
})
});
router.get('/students/edit',function(req,res){
Student.findById(parseInt(req.query.id),function(err,student){
if(err){
return res.status(500).send('server error')
}
res.render('edit.html',{
student:student
});
});
});
router.post('/students/edit',function(req,res){
Student.updateById(req.body,function(err){
if(err){
return res.status(500).send('server error')
}
res.redirect('/students')
})
});
router.get('/students/delete',function(req,res){
Student.deleateById(req.query.id,function(err){
if(err){
return res.status(500).send('server error')
}
res.redirect('/students')
});
});
// 把路由导出
module.exports=router;

router.js

/**
* student.js模块:
* 用于数据操作,只处理数据,不关心业务
*/
// 加载相关模块
var fs=require('fs');
var dbPath='./db.json';
// 获取所有学生数据列表
exports.find=function(callback){
// callback有两个参数:第一个是err,第二个是data
fs.readFile(dbPath,'utf8',function(err,data){
if(err){
return(callback(err))
}
callback(null,JSON.parse(data).students)
});
};
// 根据id获取学生信息对象
exports.findById=function(id,callback){
fs.readFile(dbPath,'utf8',function(err,data){
if(err){
return callback(err)
}
var students=JSON.parse(data).students;
var ret=students.find(function(item){
return item.id===parseInt(id)
});
callback(null,ret)
});
}
// 添加保存学生数据列表
exports.save=function(student,callback){
fs.readFile(dbPath,'utf8',function(err,data){
if(err){
return callback(err)
}
var students=JSON.parse(data).students
// 处理id唯一的,不重复
student.id=students[students.length-1].id+1
// 保存到数组
students.push(student)
// 转为字符串
var fileDate=JSON.stringify({students:students})
// 保存到文件
fs.writeFile(dbPath,fileDate,function(err){
if(err){
return callback(err)
}
callback(null)
})
});
};
// 更新学生数据列表
exports.updateById=function(student,callback){
fs.readFile(dbPath,'utf8',function(err,data){
if(err){
return callback(err)
}
var students=JSON.parse(data).students;
student.id=parseInt(student.id);
// find 是ecmascript6的方法
var stu=students.find(function(item){
return item.id===student.id
});
// 遍历拷贝对象
for(var key in student){
stu[key]=student[key]
}
// 把对象数据转为字符串
var fileDate=JSON.stringify({
students:students
});
// 保存到文件
fs.writeFile(dbPath,fileDate,function(err){
if(err){
return callback(err)
}
callback(null)
});
});
};
// 删除学生数据
exports.deleateById = function(id,callback){
fs.readFile(dbPath,'utf8',function(err,data){
if(err){
return callback(err)
}
var students=JSON.parse(data).students;
var deleteId=students.findIndex(function(item){
return item.id===parseInt(id)
});
students.splice(deleteId,1);
var fileDate=JSON.stringify({students:students});
fs.writeFile(dbPath,fileDate,function(err){
if(err){
return callback(err)
}
callback(null)
});
})
}

student.js

{
"name": "Code",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"art-template": "^4.12.2",
"body-parser": "^1.18.3",
"bootstrap": "^4.1.1",
"express": "^4.16.3",
"express-art-template": "^1.0.1"
}
}

package.json

③效果展示

学生管理系统(Nodejs)的更多相关文章

  1. 【IOS开发笔记02】学生管理系统

    端到端的机会 虽然现在身处大公司,但是因为是内部创业团队,产品.native.前端.服务器端全部坐在一起开发,大家很容易做零距离交流,也因为最近内部有一个前端要转岗过来,于是手里的前端任务好像可以抛一 ...

  2. 【IOS开发笔记01】学生管理系统(上)

    端到端的机会 虽然现在身处大公司,但是因为是内部创业团队,产品.native.前端.服务器端全部坐在一起开发,大家很容易做零距离交流,也因为最近内部有一个前端要转岗过来,于是手里的前端任务好像可以抛一 ...

  3. C程序范例(2)——学生管理系统”链表“实现

    1.对于学生管理系统,能够实现的方法有许多,但是今天我们用链表的方法来实现.虽然初学者很可能看不懂,但是不要紧,这是要在整体的系统的学习完C语言之后,我才编写出的程序.所以大家不必要担心.在这里与大家 ...

  4. jsp学习之基于mvc学生管理系统的编写

    mvc开发模式:分别是 model层 view层 Control层 在学生管理系统中,model层有学生实体类,数据访问的dao层,view层主要是用于显示信息的界面,Control层主要是servl ...

  5. java版本的学生管理系统

    import java.awt.BorderLayout; import java.awt.Color; import java.awt.Frame; import java.awt.event.Ac ...

  6. 学生管理系统-火车订票系统 c语言课程设计

    概要: C 语言课程设计一---学生管理系统 使使用 C 语言实现学生管理系统.系统实现对学生的基本信息和考试成绩的 管理.采用终端命令界面,作为系统的输入输出界面.采用文件作为信息存储介质. 功能描 ...

  7. Java学生管理系统项目案例

    这是一个不错的Java学生管理系统项目案例,希望能够帮到大家的学习吧. 分代码如下 package com.student.util; import java.sql.Connection; impo ...

  8. Java+Mysql+学生管理系统

    最近正在学java和数据库,想起以前写的学生管理系统,都是从网上下载,敷衍了事.闲来无事,也就自己写了一个,不过功能实现的不是很多. 开发语言:java: 开发环境:Mysql, java: 开发工具 ...

  9. JDBC学生管理系统--处理分页显示

    分页的思想: 假设一共有104条数据,每页显示10条数据: select * from student limit 0,10; 页数是index,第index页,对应的sql语句是: select * ...

随机推荐

  1. matplotlib 中文乱码问题

    matplotlib是Python著名的绘图库,默认并不支持中文显示,因此在不经过修改的情况下,无法正确显示中文. 本文将介绍解决这一问题的方法. 不修改文件,加两行代码即可: matplotlib. ...

  2. 【题解】Luogu P5279 [ZJOI2019]麻将

    原题传送门 希望这题不会让你对麻将的热爱消失殆尽 我们珂以统计每种牌出现的次数,不需要统计是第几张牌 判一副牌能不能和,类似这道题 对于这题: 设\(f[i][j][k][0/1]\)表示前\(i\) ...

  3. Linux中使用MegaCli工具查看、管理Raid卡信息

    MegaCli是一款管理维护硬件RAID软件,可以通过它来了解当前raid卡的所有信息,包括 raid卡的型号,raid的阵列类型,raid 上各磁盘状态,等等.通常,我们对硬盘当前的状态不太好确定, ...

  4. 2)NET CORE特性与优势

    先看看netcore有哪些特性,哪些优点,与.net frameworkd 差异吧: l  跨平台: 可以在 Windows.macOS 和 Linux 操作系统上运行. l  跨体系结构保持一致:  ...

  5. docker 安装redis mysql rabbitmq

    docker redis mysql rabbitmq 基本命令 安装redis 安装mysql 安装rabbitmq 基本命令 命令格式: docker 命令 [镜像/容器]名字 常用命令: sea ...

  6. pandas-13 时间序列操作方法pd.date_range()

    pandas-13 时间序列操作方法pd.date_range() 在pandas中拥有强大的时间序列操作方法. 使用 pd.date_range() 生成 'pandas.core.indexes. ...

  7. 【转载】C#中Convert.ToDouble方法将字符串转换为double类型

    在C#编程过程中,可以使用Convert.ToDouble方法将字符串或者其他可转换为数字的对象变量转换为double类型,Convert.ToDouble方法有多个重载方法,最常使用的一个方法将字符 ...

  8. VUE回顾基础3

    1.方法 在vue模板里函数被定义为方法来使用,将函数放在methods对象里,作为一个属性,就可以在模板里使用它 this:在方法中this指向该方法所属的组件,可以使用this方文档data对象的 ...

  9. PHP7中方法的弃用

    php7与数据库连接创建函数方法调用: function fun_conn($sql) { $con = mysqli_connect("localhost", "roo ...

  10. react学习记录(三)——状态、属性、生命周期

    react的状态state React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM) class Clock extends React.Compon ...