项目实战:Express实现学生管理系统(CRUD)

在这里插入图片描述

一、起步

  1. 初始化
    npm init -y 生成package.json文件

  2. 模板处理

    cnpm install express --save
    cnpm install bootstrap --save
    
    npm install --save art-template
    npm install --save express-art-template
    
    //两个一起安装
    npm i --save art-template express-art-template
    
    
  3. 文件目录如下:
    在这里插入图片描述

db.json文件:

{
    
    
	"students": [{
    
    
			"id": 1,
			"name": "张三三",
			"gender": "0",
			"age": "22",
			"hobbies": "吃饭、睡觉、打豆豆"
		},
		{
    
    
			"id": 2,
			"name": "张三",
			"gender": "1",
			"age": "22",
			"hobbies": "吃饭、看书、打豆豆"
		},
		{
    
    
			"id": 3,
			"name": "小娜",
			"gender": "0",
			"age": "22",
			"hobbies": "吃饭、睡觉、打豆豆"
		},
		{
    
    
			"id": 4,
			"name": "大头儿子",
			"gender": "0",
			"age": "22",
			"hobbies": "吃饭、敲代码、打豆豆"
		},
		{
    
    
			"id": 5,
			"name": "天猫",
			"gender": "0",
			"age": "27",
			"hobbies": "吃饭、睡觉、玩游戏"
		},
		{
    
    
			"id": 6,
			"name": "Rick",
			"gender": "0",
			"age": "25",
			"hobbies": "打篮球、睡觉、打豆豆"
		}


	]
}

二、路由设计

在这里插入图片描述

三、提取路由模块

在这里插入图片描述

router.js:

/* 
	router.js 路由模块
	职责: 
		处理路由
		根据不同的请求方法+请求路径设置具体的请求处理函数
	模块值则要单一,不要乱写
 */

var fs = require('fs')

// express提供了一种更好的方式,专门用来包装路由
var express = require('express')

// 1.创建一个路由容器
var router = express.Router()

// 2.把路由都挂载到router路由容器上
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!')
		}
		console.log(data) // 这里的data 是 string 类型的
		res.render('index.html', {
    
    
			fruits: [
				'苹果',
				'香蕉',
				'橘子',
				'桃子'
			],
			students: JSON.parse(data).students //将string类型的data通过JSON.parse(data)转成对象类型
		})
	})
})


router.get('/students/new', function(req, res) {
    
    
	res.send('new new new')
})


// 3.把router导出
module.exports = router








// 这样也不方便
/* module.exports = function(app) {
	app.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!')
			}
			console.log(data) // 这里的data 是 string 类型的
			res.render('index.html', {
				fruits: [
					'苹果',
					'香蕉',
					'橘子',
					'桃子'
				],
				students: JSON.parse(data).students //将string类型的data通过JSON.parse(data)转成对象类型
			})
		})
	})


	app.get('/students/new', function(req, res) {

	})
	/* app.get('/students', function(req, res) {
		
	})
	app.get('/students', function(req, res) {
		
	})
	app.get('/students', function(req, res) {
		
	})
	app.get('/students', function(req, res) {
		
	})
	app.get('/students', function(req, res) {
		
	}) 
}
 */

app.js:

/* 
	app.js入口模块
	职责:
		创建服务
		做一些服务相关的配置
			模板引擎
			body-parse 用来解析表单post请求体
			提供静态资源服务
		挂载路由
		监听端口启动服务
 */


var express = require('express')
var router =require('./router')

var app = express()

// 开放node_modules 和 public文件夹
app.use('/node_modules/', express.static('./node_modules/'))
app.use('/public/', express.static('./public/'))


// 配置模板引擎
app.engine('html', require('express-art-template'))

/* app.get('/', function(req, res) {
	
}) */



// 把路由容器挂载到app服务中
app.use(router)




app.listen(3000, function() {
    
    
	console.log("Server running... 3000")
})

四、页面准备(来自bootstrap官网提供的模板)

模板:view-source:https://v3.bootcss.com/examples/dashboard/
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
		<meta name="description" content="">
		<meta name="author" content="">
		<link rel="icon" href="../../favicon.ico">

		<title>Dashboard Template for Bootstrap</title>

		<!-- Bootstrap core CSS -->
		<!-- <link href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"> -->
		 <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">



		<!-- Custom styles for this template -->
		<link href="../public/css/dashboard.css" rel="stylesheet">


	</head>

	<body>

		<nav class="navbar navbar-inverse navbar-fixed-top">
			<div class="container-fluid">
				<div class="navbar-header">
					<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
						aria-expanded="false" aria-controls="navbar">
						<span class="sr-only">Toggle navigation</span>
						<span class="icon-bar"></span>
						<span class="icon-bar"></span>
						<span class="icon-bar"></span>
					</button>
					<a class="navbar-brand" href="#">Project name</a>
				</div>
				<div id="navbar" class="navbar-collapse collapse">
					<ul class="nav navbar-nav navbar-right">
						<li><a href="#">Dashboard</a></li>
						<li><a href="#">Settings</a></li>
						<li><a href="#">Profile</a></li>
						<li><a href="#">Help</a></li>
					</ul>
					<form class="navbar-form navbar-right">
						<input type="text" class="form-control" placeholder="Search...">
					</form>
				</div>
			</div>
		</nav>

		<div class="container-fluid">
			<div class="row">
				<div class="col-sm-3 col-md-2 sidebar">
					<ul class="nav nav-sidebar">
						<li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
						<li><a href="#">Reports</a></li>
						<li><a href="#">Analytics</a></li>
						<li><a href="#">Export</a></li>
					</ul>
					<ul class="nav nav-sidebar">
						<li><a href="">Nav item</a></li>
						<li><a href="">Nav item again</a></li>
						<li><a href="">One more nav</a></li>
						<li><a href="">Another nav item</a></li>
						<li><a href="">More navigation</a></li>
					</ul>
					<ul class="nav nav-sidebar">
						<li><a href="">Nav item again</a></li>
						<li><a href="">One more nav</a></li>
						<li><a href="">Another nav item</a></li>
					</ul>
				</div>
				<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
					<h1 class="page-header">Dashboard</h1>

					<div class="row placeholders">
						{
   
   { each fruits }}
						<div class="col-xs-6 col-sm-3 placeholder">
							<img src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="
								width="200" height="200" class="img-responsive" alt="Generic placeholder thumbnail">
							<h4>{
   
   {$value}}</h4>
							<span class="text-muted">Something else</span>
						</div>
						{
   
   { /each }}
					</div>

					<h2 class="sub-header">Section title</h2>
					<a href="#" class="btn btn-success">添加学生</a>
					<div class="table-responsive">
						<table class="table table-striped">
							<thead>
								<tr>
									<th>#</th>
									<th>姓名</th>
									<th>性别</th>
									<th>年龄</th>
									<th>爱好</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>
									</tr>
								{
   
   { /each }}
							</tbody>
						</table>
					</div>
				</div>
			</div>
		</div>

	</body>
</html>

增加添加学生页面new.html :
在这里插入图片描述

new.html:

<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
		<meta name="description" content="">
		<meta name="author" content="">
		<link rel="icon" href="../../favicon.ico">

		<title>Dashboard Template for Bootstrap</title>

		<!-- Bootstrap core CSS -->
		<!-- <link href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"> -->
		<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">



		<!-- Custom styles for this template -->
		<link href="../public/css/dashboard.css" rel="stylesheet">


	</head>

	<body>

		<nav class="navbar navbar-inverse navbar-fixed-top">
			<div class="container-fluid">
				<div class="navbar-header">
					<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
						aria-expanded="false" aria-controls="navbar">
						<span class="sr-only">Toggle navigation</span>
						<span class="icon-bar"></span>
						<span class="icon-bar"></span>
						<span class="icon-bar"></span>
					</button>
					<a class="navbar-brand" href="#">Project name</a>
				</div>
				<div id="navbar" class="navbar-collapse collapse">
					<ul class="nav navbar-nav navbar-right">
						<li><a href="#">Dashboard</a></li>
						<li><a href="#">Settings</a></li>
						<li><a href="#">Profile</a></li>
						<li><a href="#">Help</a></li>
					</ul>
					<form class="navbar-form navbar-right">
						<input type="text" class="form-control" placeholder="Search...">
					</form>
				</div>
			</div>
		</nav>

		<div class="container-fluid">
			<div class="row">
				<div class="col-sm-3 col-md-2 sidebar">
					<ul class="nav nav-sidebar">
						<li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
						<li><a href="#">Reports</a></li>
						<li><a href="#">Analytics</a></li>
						<li><a href="#">Export</a></li>
					</ul>
					<ul class="nav nav-sidebar">
						<li><a href="">Nav item</a></li>
						<li><a href="">Nav item again</a></li>
						<li><a href="">One more nav</a></li>
						<li><a href="">Another nav item</a></li>
						<li><a href="">More navigation</a></li>
					</ul>
					<ul class="nav nav-sidebar">
						<li><a href="">Nav item again</a></li>
						<li><a href="">One more nav</a></li>
						<li><a href="">Another nav item</a></li>
					</ul>
				</div>
				<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
					<h2 class="sub-header">添加学生</h2>
					<form action="/student/new" method="post">
						<div class="form-group">
							<label for="name">姓名</label>
							<input type="text" class="form-control" id="name" name="name">
							<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone
								else.</small>
						</div>
						<div class="form-group">
							<label for="sex">性别</label>
							<div class="form-check form-check-inline">
								<input class="form-check-input" type="radio" name="gender" id="inlineRadio1"
									value="0">
								<label class="form-check-label" for="inlineRadio1"></label>
								<input class="form-check-input" type="radio" name="gender" id="inlineRadio2"
									value="1">
								<label class="form-check-label" for="inlineRadio2"></label>
							</div>
						</div>
						
						
						<div class="form-group">
							<label for="age">年龄</label>
							<input type="text" class="form-control" id="age" name="age">
						</div>
						
						<div class="form-group">
							<label for="hobbies">爱好</label>
							<input type="text" class="form-control" id="hobbies" name="hobbies">
							
						</div>
						<button type="submit" class="btn btn-primary">提交</button>
					</form>
				</div>
			</div>
		</div>

	</body>
</html>

增加编辑学生页面:

在这里插入图片描述

<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
		<meta name="description" content="">
		<meta name="author" content="">
		<link rel="icon" href="../../favicon.ico">

		<title>Dashboard Template for Bootstrap</title>

		<!-- Bootstrap core CSS -->
		<!-- <link href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"> -->
		<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">



		<!-- Custom styles for this template -->
		<link href="../public/css/dashboard.css" rel="stylesheet">


	</head>

	<body>

		<nav class="navbar navbar-inverse navbar-fixed-top">
			<div class="container-fluid">
				<div class="navbar-header">
					<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
						aria-expanded="false" aria-controls="navbar">
						<span class="sr-only">Toggle navigation</span>
						<span class="icon-bar"></span>
						<span class="icon-bar"></span>
						<span class="icon-bar"></span>
					</button>
					<a class="navbar-brand" href="#">Project name</a>
				</div>
				<div id="navbar" class="navbar-collapse collapse">
					<ul class="nav navbar-nav navbar-right">
						<li><a href="#">Dashboard</a></li>
						<li><a href="#">Settings</a></li>
						<li><a href="#">Profile</a></li>
						<li><a href="#">Help</a></li>
					</ul>
					<form class="navbar-form navbar-right">
						<input type="text" class="form-control" placeholder="Search...">
					</form>
				</div>
			</div>
		</nav>

		<div class="container-fluid">
			<div class="row">
				<div class="col-sm-3 col-md-2 sidebar">
					<ul class="nav nav-sidebar">
						<li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
						<li><a href="#">Reports</a></li>
						<li><a href="#">Analytics</a></li>
						<li><a href="#">Export</a></li>
					</ul>
					<ul class="nav nav-sidebar">
						<li><a href="">Nav item</a></li>
						<li><a href="">Nav item again</a></li>
						<li><a href="">One more nav</a></li>
						<li><a href="">Another nav item</a></li>
						<li><a href="">More navigation</a></li>
					</ul>
					<ul class="nav nav-sidebar">
						<li><a href="">Nav item again</a></li>
						<li><a href="">One more nav</a></li>
						<li><a href="">Another nav item</a></li>
					</ul>
				</div>
				<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
					<h2 class="sub-header">编辑学生</h2>
					<form action="/students/edit" method="post">
						<!-- 用来放一些不希望被用户看见,但是需要被提交到服务端的数据 -->
						<input type="hidden" name="id" value="{
     
     { student.id }}">
						<div class="form-group">
							<label for="name">姓名</label>
							<input value="{
     
     { student.name }}" type="text" class="form-control" id="name" name="name">
							
						</div>
						<div class="form-group">
							<label for="sex">性别</label>
							<div class="form-check form-check-inline">
								<input class="form-check-input" type="radio" name="gender" id="inlineRadio1"
									value="0">
								<label class="form-check-label" for="inlineRadio1"></label>
								<input class="form-check-input" type="radio" name="gender" id="inlineRadio2"
									value="1">
								<label class="form-check-label" for="inlineRadio2"></label>
							</div>
						</div>
						
						
						<div class="form-group">
							<label for="age">年龄</label>
							<input value="{
     
     { student.age }}"  type="text" class="form-control" id="age" name="age">
						</div>
						
						<div class="form-group">
							<label for="hobbies">爱好</label>
							<input value="{
     
     { student.hobbies }}"  type="text" class="form-control" id="hobbies" name="hobbies">
							
						</div>
						<button type="submit" class="btn btn-primary">提交</button>
					</form>
				</div>
			</div>
		</div>

	</body>
</html>

编写router.js文件

因为需要拿到post请求体中的数据,所以需要安装第三方插件来帮助我们获取请求体数据
在该项目文件中,cmd命令行输入命令cnpm install --save body-parser
在这里插入图片描述

由于接下来的一系列业务操作都需要处理文件数据,所以我们需要封装Student.js

student.js:

/* 
	student.js 
	数据操作文件模块
	职责: 操作文件中的数据,只处理数据,不关心业务
 */

var fs = require('fs')

var dbPath = './db.json'

/* 获取所有学生列表 */
/* 
	callback中的参数
		第一个参数是 err
			成功是 null
			错误是 错误对象
		第二个参数是 结果
			成功是数组
			错误是 undefined
 */
exports.find = function(callback) {
    
    
	fs.readFile(dbPath, 'utf8', function(err, data) {
    
    
		if (err) {
    
    
			return callback(err)
		}
		callback(null, JSON.parse(data).students)
	})
}



/* 添加保存学生 */
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 fileData = JSON.stringify({
    
    
			students: students
		})

		fs.writeFile(dbPath, fileData, function(err) {
    
    
			if (err) {
    
    
				// 错误就 把错误对象传递给callback
				return callback(err)
			}
			// 成功就是没有错误, 所以错误对象是null
			callback(null)
		})
	})
}



/* 更新学生 */
exports.updateById = function(student, callback) {
    
    
	fs.readFile(dbPath, 'utf8', function(err, data) {
    
    
		if (err) {
    
    
			return callback(err)
		}
		// 注意:这里记得把 id 统一转换为数字类型
		var students = JSON.parse(data).students
		student.id = parseInt(student.id)
		// 你要修改谁,就需要把谁找出来
		// EcmaScript 6 中的一个数组方法:find
		// 需要接收一个函数作为参数
		// 当某个遍历项符合 item.id === student.id 条件的时候,find 会终止遍历,同时返回遍历项
		var stu = students.find(function(item) {
    
    
			return item.id === student.id
		})

		// 遍历拷贝对象
		for (var key in student) {
    
    
			stu[key] = student[key]
		}

		// 把对象数据转换为字符串
		var fileData = JSON.stringify({
    
    
			students: students
		})

		// 把字符串保存到文件中
		fs.writeFile(dbPath, fileData, function(err) {
    
    
			if (err) {
    
    
				// 错误就是把错误对象传递给它
				return callback(err)
			}
			// 成功就没错,所以错误对象是 null
			callback(null)
		})

	})
}

/* 调用格式 */
/* updateById({
	id: 1,
	name: 'xx',
	age: 15
},function(err) {
	
}) */


/**
 * 根据 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 ret = students.find(function (item) {
    
    
      return item.id === parseInt(id)
    })
    callback(null, ret)
  })
}
/* findById()调用方式 */
/* Student.findById(id, function(err, student) {
	
}) */

/* 删除学生 */
exports.deleteById = function(id, callback) {
    
    
	fs.readFile(dbPath, 'utf8', function(err, data) {
    
    
		if (err) {
    
    
			return callback(err)
		}
		var students = JSON.parse(data).students
		
		// findIndex 方法专门用来根据条件查找元素的下标
		var deleteId = students.findIndex(function(item) {
    
    
			return item.id ===parseInt(id)
		})
		
		// 根据下标从数组中删除对应的学生对象
		students.splice(deleteId, 1)
		
		// 把对象数据转换为字符串
		var fileData = JSON.stringify({
    
    
			students: students
		})
		
		// 把字符串保存到文件中
		fs.writeFile(dbPath, fileData, function(err) {
    
    
			if (err) {
    
    
				// 错误就是把错误对象传递给它
				return callback(err)
			}
			// 成功就没错,所以错误对象是 null
			callback(null)
		})
	})
}

router.js:

/* 
	router.js 路由模块
	职责: 
		处理路由
		根据不同的请求方法+请求路径设置具体的请求处理函数
	模块值则要单一,不要乱写
 */

var fs = require('fs')
var Student = require('./student')



// express提供了一种更好的方式,专门用来包装路由
var express = require('express')
// 1.创建一个路由容器
var router = express.Router()
// 2.把路由都挂载到router路由容器上
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!')
		}
		console.log(data) // 这里的data 是 string 类型的
		res.render('index.html', {
			fruits: [
				'苹果',
				'香蕉',
				'橘子',
				'桃子'
			],
			students: JSON.parse(data).students //将string类型的data通过JSON.parse(data)转成对象类型
		})
	}) */
	Student.find(function(err, students) {
    
    
		if (err) {
    
    
			return res.status(500).send('Server error!')
		}
		res.render('index.html', {
    
    
			fruits: [
				'苹果',
				'香蕉',
				'橘子',
				'桃子'
			],
			students: students
		})
	})
})

router.get('/students/new', function(req, res) {
    
    
	res.render('new.html')
})

router.post('/students/new', function(req, res) {
    
    
	// 1.获取表单数据
	// 2.处理
	//  	将数据保存到db.json文件中用以持久化保存
	//       	先读取文件数据,转成对象
	//			然后往对象中push数据
	//			然后把对象转为字符串
	//			然后把字符串再次写入文件
	// 3.发送响应
	console.log(req.body)
	var student = req.body
	Student.save(student, function(err) {
    
    
		if(err) {
    
    
			return res.status(500).send('Server error!')
		}
		res.redirect('/students')
	})
})

router.get('/students/edit', function(req, res) {
    
    
	// 1. 在客户端的列表页中处理链接问题(需要有id参数)
	// 2. 获取要编辑的学生id
	// 3. 渲染编辑页面
	//      根据id把学生信息查出来
	//		使用模板引擎渲染页面
	console.log(req.query.id)
	Student.findById(parseInt(req.query.id), function(err, student) {
    
    
		if (err) {
    
    
			return res.status(500).send('Server error!')
		}
		console.log(student)
		res.render('edit.html', {
    
    
			student:  student
		})
	})
	
	
})

router.post('/students/edit', function(req, res) {
    
    
	// 1.获取表单数据 req.body
	// 2.更新 Student.updateById()
	// 2.发送响应
	console.log(req.body)
	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) {
    
    
	// 1.获取要删除的id
	// 2.根据id执行删除操作
	// 3.根据操作结果发送响应数据
	console.log(req.query.id)
	Student.deleteById(req.query.id, function(err) {
    
    
		if(err) {
    
    
			return res.status(500).send('Server error!')
		}
		console.log('删除成功')
		res.redirect('/students')
	})
})

// 3.把router导出
module.exports = router








// 这样也不方便
/* module.exports = function(app) {
	app.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!')
			}
			console.log(data) // 这里的data 是 string 类型的
			res.render('index.html', {
				fruits: [
					'苹果',
					'香蕉',
					'橘子',
					'桃子'
				],
				students: JSON.parse(data).students //将string类型的data通过JSON.parse(data)转成对象类型
			})
		})
	})


	app.get('/students/new', function(req, res) {

	})
	/* app.get('/students', function(req, res) {
		
	})
	app.get('/students', function(req, res) {
		
	})
	app.get('/students', function(req, res) {
		
	})
	app.get('/students', function(req, res) {
		
	})
	app.get('/students', function(req, res) {
		
	}) 
}
 */

总结

步骤

  • 处理模板

  • 配置静态开放资源

  • 配置模板引擎

  • 简单的路由,/studens渲染静态页出来

  • 路由设计

  • 提取路由模块

  • 由于接下来的一系列业务操作都需要处理文件数据,所以我们需要封装Student.js’

  • 先写好student.js文件结构

    • 查询所有学生列别哦的API
    • findById
    • save
    • updateById
    • deleteById
  • 实现具体功能

    • 通过路由收到请求
    • 接受请求中的参数(get,post)
      • req.query
      • req.body
    • 调用数据操作API处理数据
    • 根据操作结果给客户端发送请求
  • 业务功能顺序

    • 列表
    • 添加
    • 编辑
    • 删除

猜你喜欢

转载自blog.csdn.net/weixin_44827418/article/details/115263925