利用Express实现ADUS项目
使用Express可以快速地实现一个包含增删改查(CRUD)功能的Web项目,下面是一个基于Express实现的简单ADUS(添加、显示、更新、删除、搜索)项目
模块化思想
模块如何划分:
- 模块职责要单一
在使用Express实现一个CRUD项目时,通常可以将不同的功能模块划分为不同的路由和控制器,以实现代码的可读性和可维护性。在实现模块划分时,需要注意以下几点:
- 尽量保持模块功能单一。一个模块应该只包含一个相关的功能,以便于代码的维护和管理。
- 将路由和控制器分离。路由应该负责请求的转发和参数的解析,而控制器应该负责具体的业务逻辑。
- 使用中间件实现公共功能。比如身份验证、请求日志记录等功能可以使用中间件实现,避免代码重复。
- 将模块拆分为多个文件。当一个模块变得庞大时,可以将其拆分为多个文件,以便于代码的管理和维护。可以使用Node.js的模块系统来实现文件的拆分和组合。
javascript模块化:
- Node 中的 CommonJS
- 浏览器中的:
- AMD require.js
- CMD sea.js
- es6中增加了官方支持
起步
- 初始化
- 模板处理
路由设计
请求方法 | 请求路径 | get参数 | post参数 | 备注 |
---|---|---|---|---|
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.js:
代码语言:javascript复制/**
* router.js路由模块
* 职责:
* 处理路由
* 根据不同的请求方法 请求路径设置具体的请求函数
* 模块职责要单一,我们划分模块的目的就是增强代码的可维护性,提升开发效率
*/
var fs = require('fs');
// Express专门提供了一种更好的方式
// 专门用来提供路由的
var express = require('express');
// 1 创建一个路由容器
var router = express.Router();
// 2 把路由都挂载到路由容器中
router.get('/students', function(req, res) {
// res.send('hello world');
// readFile的第二个参数是可选的,传入utf8就是告诉他把读取到的文件直接按照utf8编码,直接转成我们认识的字符
// 除了这样来转换,也可以通过data.toString()来转换
fs.readFile('./db.json', 'utf8', function(err, data) {
if (err) {
return res.status(500).send('Server error.')
}
// 读取到的文件数据是string类型的数据
// console.log(data);
// 从文件中读取到的数据一定是字符串,所以一定要手动转换成对象
var students = JSON.parse(data).students;
res.render('index.html', {
// 读取文件数据
students:students
})
})
});
router.get('/students/new',function(req,res){
res.render('new.html')
});
router.get('/students/edit',function(req,res){
});
router.post('/students/edit',function(req,res){
});
router.get('/students/delete',function(req,res){
});
// 3 把router导出
module.exports = router;
app.js:
代码语言:javascript复制var router = require('./router');
// router(app);
// 把路由容器挂载到app服务中
// 挂载路由
app.use(router);
设计操作数据的API文件模块
es6中的find和findIndex:
find接受一个方法作为参数,方法内部返回一个条件
find会便利所有的元素,执行你给定的带有条件返回值的函数
符合该条件的元素会作为find方法的返回值
如果遍历结束还没有符合该条件的元素,则返回undefined
代码语言:javascript复制/**
* student.js
* 数据操作文件模块
* 职责:操作文件中的数据,只处理数据,不关心业务
*/
var fs = require('fs');
/**
* 获取所有学生列表
* return []
*/
exports.find = function(){
}
/**
* 获取添加保存学生
*/
exports.save = function(){
}
/**
* 更新学生
*/
exports.update = function(){
}
/**
* 删除学生
*/
exports.delete = function(){
}
步骤
- 处理模板
- 配置静态开放资源
- 配置模板引擎
- 简单的路由,/studens渲染静态页出来
- 路由设计
- 提取路由模块
- 由于接下来的一系列业务操作都需要处理文件数据,所以我们需要封装Student.js'
- 先写好student.js文件结构
- 查询所有学生列别哦的API
- findById
- save
- updateById
- deleteById
- 实现具体功能
- 通过路由收到请求
- 接受请求中的参数(get,post)
- req.query
- req.body
- 调用数据操作API处理数据
- 根据操作结果给客户端发送请求
- 业务功能顺序
- 列表
- 添加
- 编辑
- 删除
子模板和模板的继承(模板引擎高级语法)【include,extend,block】
注意:
模板页:
代码语言:javascript复制<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>模板页</title>
<link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.css"/>
{{ block 'head' }}{{ /block }}
</head>
<body>
<!-- 通过include导入公共部分 -->
{{include './header.html'}}
<!-- 留一个位置 让别的内容去填充 -->
{{ block 'content' }}
<h1>默认内容</h1>
{{ /block }}
<!-- 通过include导入公共部分 -->
{{include './footer.html'}}
<!-- 公共样式 -->
<script src="/node_modules/jquery/dist/jquery.js" ></script>
<script src="/node_modules/bootstrap/dist/js/bootstrap.js" ></script>
{{ block 'script' }}{{ /block }}
</body>
</html>
模板的继承:
代码语言:txt复制header页面:
代码语言:javascript复制<div id="">
<h1>公共的头部</h1>
</div>
代码语言:txt复制footer页面:
代码语言:javascript复制<div id="">
<h1>公共的底部</h1>
</div>
模板页的使用:
代码语言:javascript复制<!-- 继承(extend:延伸,扩展)模板也layout.html -->
<!-- 把layout.html页面的内容都拿进来作为index.html页面的内容 -->
{{extend './layout.html'}}
<!-- 向模板页面填充新的数据 -->
<!-- 填充后就会替换掉layout页面content中的数据 -->
<!-- style样式方面的内容 -->
{{ block 'head' }}
<style type="text/css">
body{
background-color: skyblue;
}
</style>
{{ /block }}
{{ block 'content' }}
<div id="">
<h1>Index页面的内容</h1>
</div>
{{ /block }}
<!-- js部分的内容 -->
{{ block 'script' }}
<script type="text/javascript">
</script>
{{ /block }}
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!