MongoDB+模板引擎 项目实例-学生档案管理
目标:模板引擎应用,强化 node.js 项目制作流程。
知识点:http请求响应、数据库、模板引擎、静态资源访问。
1、建立项目文件夹并生成项目描述文件 package.json
1.1、创建 students 文件夹
1.2、生成项目描述文件 package.json
在命令行工具中切换到当前项目的根目录下,输入:
npm init -y
2、创建网站服务器,实现客户端和服务器端通信
2.1、创建网站服务器
在根目录下新建 app.js 文件:
// 引入 http 模块 const http = require('http'); // 创建网站服务器 const app = http.createServer();
2.2、添加请求事件,实现通信
// 引入 http 模块 const http = require('http'); // 创建网站服务器 const app = http.createServer(); // 当客户端访问服务器端的时候 app.on('request', (req, res) => { res.end('ok'); }); app.listen(80); console.log('服务器启动成功');
在命令行工具中开启服务器:
nodemon app.js
再打开浏览器,输入:http://localhost/
可以看到,响应成功:
3、连接数据库并根据需求设计学员信息表
3.1、连接数据库
1、安装 mongoose,在命令行工具中输入:
npm install mongoose
然后重启开启服务器:nodemon app.js
2、连接数据库
在 app.js 文件中添加:
// 引入 http 模块 const http = require('http'); const mongoose = require('mongoose'); // 连接数据库 mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true, useUnifiedTopology: true}) .then(() => console.log('数据库连接成功')) .catch(() => console.log('数据库连接失败')) // 创建网站服务器 const app = http.createServer(); // 当客户端访问服务器端的时候 app.on('request', (req, res) => { res.end('ok'); }); app.listen(80); console.log('服务器启动成功');
然后在命令行工具中可以看到:数据库连接成功的提示。
注意:如果没启动 MongoDB,记得要先启动:net start mongoDB
我们上次说过要把数据库的代码分离出去,不要都写在一个文件中
所以新建 model 文件夹,创建 connect.js 文件,然后把数据库连接部分的代码剪切过来。
const mongoose = require('mongoose'); // 连接数据库 mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true, useUnifiedTopology: true}) .then(() => console.log('数据库连接成功')) .catch(() => console.log('数据库连接失败'))
然后回到 app.js 中导入connect
require('./model/connect');
3.2、设计学员信息表
1、设计用户集合用到的字段
在 model 目录下新建 user.js 文件:
const mongoose = require('mongoose'); // 创建学生集合规则 const studentsSchema = new mongoose.Schema({ name:{ type: String, required: true, minlength: 2, maxlength: 10 }, age: { type: Number, min: 10, max: 25 }, sex: { type:String }, email: String, hobbies: [String], collage: String, enterDate: { type: Date, default: Date.now } }); // 创建学生信息集合 const Student = mongoose.model('Student', studentsSchema); // 将学生信息集合进行导出 module.exports = Student;
回到 app.js 文件中,导入 Student
const Student = require('./model/user');
4、创建路由并实现页面模板呈递
第三方模块 router
功能:实现路由。
使用步骤:
1、获取路由对象
2、调用路由对象提供的方法创建路由
3、启用路由,使路由生效
示例代码:
const getRouter = require('router');
const router = getRouter();
router.get('/add', (req, res) => {
res.end('hello world')
})
server.on('request', (req. res) => {
router(req, res)
})
下载安装:
npm install router
重新启动项目:nodemon app.js
回到app.js 文件中,引入 router 模块:
// 引入 router 模块 const getRouter = require('router'); // 获取路由对象 const router = getRouter(); router.get('/test', (req, res) => { res.end('test') }) router.get('/index', (req, res) => { res.end('index') }) // 当客户端访问服务器端的时候 app.on('request', (req, res) => { // res.end('ok'); router(req, res, () => { }) });
此时打开浏览器,输入:http://localhost/test,页面上可以看到 test ;同样输入 http://localhost/index,页面可以显示index。
4.1、创建当前项目路由
// 添加学生档案信息页面 router.get('/add', (req, res) => { res.end('add') }) // 学生档案信息列表页面 router.get('/list', (req, res) => { res.end('list') })
4.2、呈现对应的页面
1、安装模板引擎
在命令行工具输入:npm install art-template
在项目根目录下,新建 views 文件夹, 把静态页面粘贴过来;并在项目根目录下,新建 public 文件夹,把 css 文件站提过来。
在 app.js 文件中引入模板引擎:
const template = require('art-template');
接下来在对应的路由中,渲染模板引擎,并把渲染的结果响应给客户端
2、配置模板的根目录
const path = require('path'); // 配置模板的根目录 template.defaults.root = path.join(__dirname, 'views'); // 添加学生档案信息页面 router.get('/add', (req, res) => { const html = template('index.art', {}) res.end(html) }) // 学生档案信息列表页面 router.get('/list', (req, res) => { const html = template('list.art', {}) res.end(html) })
在命令行工具开启服务:nodemon app.js
回到浏览器中,输入:http://localhost/add
会发现i服务器一直请求,点击刷新按钮,可以看到没有样式,查看源码可以看到页面还引用了一个 css 样式文件。
第三方模块 serve-static
功能:实现静态资源访问服务。
步骤:
1、引入 serve-static 模块获取创建静态资源服务功能的方法
2、调用方法创建静态资源服务并指定静态资源服务目录
3、启动静态资源服务功能
示例代码:
const serveStatic = require('serve-static')
const serve = serveStatic('public')
server.on('request', () => {
serve(req. res)
})
server.listen(3000)
5、实现静态资源访问
5.1、下载安装 serve-static
npm install serve-static
5.2、引入静态资源访问 serve-static 模块
// 引入静态资源访问模块 const serveStatic = require('serve-static');
5.3、实现静态资源访问服务
// 实现静态资源访问服务 const serve = serveStatic(path.join(__dirname, 'public'));
5.4、启用静态资源访问服务功能
// 当客户端访问服务器端的时候 app.on('request', (req, res) => { // 启用路由功能 router(req, res, () => {}) // 启用静态资源访问服务功能 serve(req, res, () => {}) });
回到浏览器刷新页面,可以看到样式出来了:
6、实现学生信息添加功能
6.1、在模板的表单中指定请求地址与请求方式
打开 views 目录下的 index.art 文件,添加请求地址及请求方式
<form method="post" action="/add">
6.2、为每一个表单项添加 name 属性
<input class="normal" type="text" autofocus placeholder="请输入姓名" name="name"> <input class="normal" type="text" placeholder="请输入年龄" name="age"> <input type="radio" value="0" name="sex"> 男 <input type="radio" value="1" name="sex"> 女 <input class="normal" type="text" placeholder="请输入邮箱地址" name="email"> <input type="checkbox" value="0" name="hobbies"> 敲代码 <input type="checkbox" value="1" name="hobbies"> 打篮球 <input type="checkbox" value="1" name="hobbies"> 睡觉 <select class="normal" name="collage"> <input type="date" class="normal" name="enterDate">
6.3、添加实现学生信息功能路由
// 实现学生信息添加功能路由 router.post('/add', (req, res) => { })
6.4、接收客户端传递过来的学生信息
// 实现学生信息添加功能路由 router.post('/add', (req, res) => { // 接收用户提交的信息 let fromData= ''; // 当有参数传递的时候会触发 data 事件 req.on('data', param => { fromData += param; }); // 当参数接收完毕的时候会触发 end 事件 req.on('end', async () => { console.log(querystring.parse(fromData)) res.end('123'); }); })
回到浏览器中刷新页面,随便输入一些信息后提交;然后可以看到页面显示:123
打开命令行工具,可以看到:参数已经接受过来了
6.5、将学生信息添加到数据库中
// 实现学生信息添加功能路由 router.post('/add', (req, res) => { // 接收用户提交的信息 let fromData= ''; // 当有参数传递的时候会触发 data 事件 req.on('data', param => { fromData += param; }); // 当参数接收完毕的时候会触发 end 事件 req.on('end', async () => { // 将用户提交的信息添加到数据库中 await Student.create( querystring.parse(fromData)); // 重定向 状态码是301 // Location 跳转地址 res.writeHead(301, { Location: '/list' }); res.end(); }); })
6.6、将页面信息重定向到学生信息列表页面
回到浏览器中刷新页面,重新提交一些信息后,会重定向到 /list 路由
打开 Compass 软件,可以看到 playground 下多了一个 students 集合,里面有一条刚提交的数据
7、实现学生信息展示功能
7.1、从数据库中将所有的学生信息查询出来
在 app.js 中继续编辑代码:
// 学生档案信息列表页面 router.get('/list', async (req, res) => { // 查询用户信息 let students = await Student.find() console.log(students); const html = template('list.art', {}) res.end(html) })
回到浏览器中刷新 /list 页面,在命令行工具中可以看到:
7.2、通过模板引擎将学生信息和 HTML 模板进行拼接
继续编辑 app.js 文件:
// 学生档案信息列表页面 router.get('/list', async (req, res) => { // 查询用户信息 let students = await Student.find() console.log(students); const html = template('list.art', { students: students }) res.end(html) })
打开 list.art 文件,添加循环:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>学员信息</title> <link rel="stylesheet" href="./css/list.css"> </head> <body> <table> <caption>学员信息</caption> <tr> <th>姓名</th> <th>年龄</th> <th>性别</th> <th>邮箱地址</th> <th>爱好</th> <th>所属学院</th> <th>入学时间</th> </tr> {{each students}} <tr> <th>{{$value.name}}</th> <th>{{$value.age}}}</th> <th>{{$value.sex}}</th> <th>{{$value.email}}</th> <th>{{$value.hobbies}}</th> <th>{{$value.collage}}</th> <th>{{$value.enterDate}}</th> </tr> {{/each}} </table> </body> </html>
回到浏览器刷新 /list 页面,可以看到数据渲染出来了:
这里可以看出三个问题:性别、爱好、入学时间。
7.3、将拼接好的 HTML 模板响应给客户端
解决性别问题:
<th>{{$value.sex == '0' ? '男' : '女'}}</th>
解决爱好问题:
打开 index.art 文件,修改下:
爱好: <input type="checkbox" value="敲代码" name="hobbies"> 敲代码 <input type="checkbox" value="打篮球" name="hobbies"> 打篮球 <input type="checkbox" value="睡觉" name="hobbies"> 睡觉
再重新添加一条学生信息:
可以看到爱好已经显示了,但是格式还是不对,还要进行处理:
<th> {{each $value.hobbies}} <span>{{$value}}</span> {{/each}} </th>
刷新浏览器,可以看到:爱好的格式已经正常了
解决时间问题:
第三方模板 dateformat 处理时间格式
下载安装:
npm install dateformat
然后重新开启服务:nodemon app.js
修改 app.js 文件:
// 引入处理日期的第三方模块 const dateFormat = require('dateformat'); // 导入模板变量 处理日期格式的方法 template.defaults.imports.dateFormat = dateFormat;
回到 list.art 文件:
<th>{{dateFormat($value.enterDate, "yyyy-mm-dd hh:mm")}}</th>
在浏览器刷新页面,可以看到:日期格式也正常了
此时功能都实现了。
但是发现 app.js 中路由部分的代码还可以分离出去
新建 route 目录,并在目录下 新建 index.js 文件,把 app.js 中路由部分的代码剪切过来:
// 引入 router 模块 const getRouter = require('router'); // 获取路由对象 const router = getRouter(); // 学生信息集合 const Student = require('../model/user'); // 引入模板引擎 const template = require('art-template'); // 处理请求参数模块 const querystring = require('querystring'); // 添加学生档案信息页面 router.get('/add', (req, res) => { const html = template('index.art', {}) res.end(html) }) // 学生档案信息列表页面 router.get('/list', async (req, res) => { // 查询用户信息 let students = await Student.find() console.log(students); const html = template('list.art', { students: students }) res.end(html) }) // 实现学生信息添加功能路由 router.post('/add', (req, res) => { // 接收用户提交的信息 let fromData= ''; // 当有参数传递的时候会触发 data 事件 req.on('data', param => { fromData += param; }); // 当参数接收完毕的时候会触发 end 事件 req.on('end', async () => { // 将用户提交的信息添加到数据库中 await Student.create( querystring.parse(fromData)); // 重定向 状态码是301 // Location 跳转地址 res.writeHead(301, { Location: '/list' }); res.end(); }); }) module.exports = router;
修改后的 app.js 文件:
// 引入 http 模块 const http = require('http'); // 引入模板引擎 const template = require('art-template'); // 引入 path 慕课 const path = require('path'); // 引入静态资源访问模块 const serveStatic = require('serve-static'); // 引入处理日期的第三方模块 const dateFormat = require('dateformat'); const router = require('./route/index'); // 实现静态资源访问服务 const serve = serveStatic(path.join(__dirname, 'public')); // 配置模板的根目录 template.defaults.root = path.join(__dirname, 'views'); // 导入模板变量 处理日期格式的方法 template.defaults.imports.dateFormat = dateFormat; // 数据库连接 require('./model/connect'); // 创建网站服务器 const app = http.createServer(); // 当客户端访问服务器端的时候 app.on('request', (req, res) => { // 启用路由功能 router(req, res, () => {}) // 启用静态资源访问服务功能 serve(req, res, () => {}) }); app.listen(80); console.log('服务器启动成功');
回到浏览器刷新,重新测试下功能。OK,没有影响,都正常。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?
· RFID实践——.NET IoT程序读取高频RFID卡/标签