node.js实现学生信息录入系统
上篇写了一下node的常用的一些方法,下面我简单写了一个实例,大家可以参照上篇博客来看,方便我们更好的理解消化node。这是通过node实现学生信息的录入,修改,留言等功能。
资源加载包(package.json)
资源包npm下载即可(执行 npm i 命令)
{
"name": "curd-express",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"art-template": "^4.13.2",
"body-parser": "^1.18.3",
"bootstrap": "^3.3.7",
"express": "^4.16.4",
"express-art-template": "^1.0.1",
"init": "^0.1.2"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
node接口
1.资源包引入
const fs = require("fs");
const url = require("url");
//引入express框架
const express = require("express");
//调用express方法
let app = express();
//模板引擎
const template = require("art-template")
//模板引擎简化(不用写读取页面,直接用res.render("index.html",abc);这样去写)
app.engine("html",require("express-art-template"));
//post请求需要引入
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
//静态资源加载
app.use("/node_modules",express.static("./node_modules"));
//css样式引入
app.use("/public",express.static("./public"));
2.读取JSON文件,加载首页
app.get("/student",(req,res)=>{
// 取到json数据,转译后取到数组
fs.readFile("db.json",(err,data)=>{
let strdata = data.toString();
strdata = JSON.parse(strdata);
//放入
let strdata1 = strdata["students"];
let abc = {
list:strdata1
};
res.render("index.html",abc);
})
})
3.添加信息页面(静态无操作)
app.get("/new",(req,res)=>{
res.render("addStu.html");
})
4.添加数据信息操作
app.post("/mes",(req,res)=>{
res.redirect("/student");
fs.readFile("db.json",(err,data)=>{
//将二进制的数据转换为字符串
let strdata = data.toString();
//将字符串转换为json对象
strdata = JSON.parse(strdata);
let stuArr = strdata["students"];
let last = stuArr[stuArr.length - 1];
let id = last.id;
let query = req.body;
query.id = id + 1;
stuArr.push(query);
//因为nodejs的写入文件只认识字符串或者二进制数
//所以把json对象转换成字符串重新写入json文件中
let str = JSON.stringify(strdata);
fs.writeFile("db.json",str,function(err){
})
})
})
5.编辑页面
app.get("/edit",(req,res)=>{
let urlObj = url.parse(req.url,true);
// console.log(urlObj.query.id)
fs.readFile("db.json",(err,data)=>{
//将二进制的数据转换为字符串
let strdata = data.toString();
//将字符串转换为json对象
strdata = JSON.parse(strdata);
let stuArr = strdata["students"];
let index = urlObj.query.id;
//将字符串转为整数,如果parseInt的参数不是字符串,则会先转为字符串再转换
index = parseInt(index);
let i = 0;
stuArr.forEach(value=>{
if(value.id === index){
//将修改内容放入页面更新页面可修改区域
res.render("updataStu.html",stuArr[i]);
//console.log(stuArr[i]);
}
i++;
});
});
});
6.更新数据
//在页面中/doedit的后面拼接了当前value对应的id
app.post("/doedit",(req,res)=>{
//获取对应url中所有的数据
let urlObj = url.parse(req.url,true);
//取到对应点击的id值
console.log(urlObj.query.id);
//读取json文件
fs.readFile("db.json",(err,data)=>{
let dataSource = data.toString();
//将字符串转换为json对象
dataSource = JSON.parse(dataSource);
let students = dataSource["students"];
let index = urlObj.query.id;
index = parseInt(index);
let i = 0;
//遍历students的json中的value值
students.forEach(value=>{
//若可以和所点击下标index匹配,执行
if(value.id === index){
//删除原本数据
students.splice(i,1);
let query = req.body;
query.id = value.id;
//替换新数据
students.splice(i,0,query);
let str = JSON.stringify(dataSource);
fs.writeFile("db.json",str,err=>{});
res.redirect("/student");
}
i++;
});
});
});
7.删除整条数据接口
//在页面中/del的后面拼接了当前value对应的id
app.get("/del",(req,res)=>{
let urlObj = url.parse(req.url,true);
//读取json文件
fs.readFile("db.json",(err,data)=>{
//将二进制的数据转换为字符串
let strdata = data.toString();
//将字符串转换为json对象
strdata = JSON.parse(strdata);
let stuArr = strdata["students"];
//获取当前点击的id
let index = urlObj.query.id;
index = parseInt(index);
let i = 0;
stuArr.forEach(value=>{
if(value.id === index){
//从第i个开始删除一个
stuArr.splice(i,1);
let str = JSON.stringify(strdata);
console.log(str)
fs.writeFile("db.json",str,err=>{});
//删除后跳转首页页面
res.redirect("/student");
}
i++;
});
});
});
端口号(自拟)
app.listen(8080);//部分端口号被占用,可自行百度。
页面
以下全部均需用到public.css文件和[email protected]框架
为方便使用,下面的三个HTML文件中已引入
- css文件(我的命名及路径为public/css/dashboard.css)
/*
* Base structure
*/
/* Move down content because we have a fixed navbar that is 50px tall */
body {
padding-top: 50px;
}
/*
* Global add-ons
*/
.sub-header {
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
/*
* Top navigation
* Hide default border to remove 1px line.
*/
.navbar-fixed-top {
border: 0;
}
/*
* Sidebar
*/
/* Hide for mobile, show later */
.sidebar {
display: none;
}
@media (min-width: 768px) {
.sidebar {
position: fixed;
top: 51px;
bottom: 0;
left: 0;
z-index: 1000;
display: block;
padding: 20px;
overflow-x: hidden;
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
background-color: #f5f5f5;
border-right: 1px solid #eee;
}
}
/* Sidebar navigation */
.nav-sidebar {
margin-right: -21px; /* 20px padding + 1px border */
margin-bottom: 20px;
margin-left: -20px;
}
.nav-sidebar > li > a {
padding-right: 20px;
padding-left: 20px;
}
.nav-sidebar > .active > a,
.nav-sidebar > .active > a:hover,
.nav-sidebar > .active > a:focus {
color: #fff;
background-color: #428bca;
}
/*
* Main content
*/
.main {
padding: 20px;
}
@media (min-width: 768px) {
.main {
padding-right: 40px;
padding-left: 40px;
}
}
.main .page-header {
margin-top: 0;
}
/*
* Placeholder dashboard ideas
*/
.placeholders {
margin-bottom: 30px;
text-align: center;
}
.placeholders h4 {
margin-bottom: 0;
}
.placeholder {
margin-bottom: 20px;
}
.placeholder img {
display: inline-block;
border-radius: 50%;
}
1.首页页面
(1)效果
(2)代码页
<!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">
<!-- 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">
<a href="/new"><button type="button" class="btn btn-success" >添加学生</button></a>
<h2 class="sub-header">学生列表</h2>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>爱好</th>
<th>操作</th>
</tr>
</thead>
//可用模板引擎在后台动态替换部分
//这里需在后台动态引入art-template资源包
//开始
<tbody>
//这里相当于遍历多条信息
{{each list}}
<tr>
<td>{{$value.id}}</td>
<td>{{$value.name}}</td>
<td>{{$value.age}}</td>
<td>{{$value.gender}}</td>
<td>{{$value.hobbies}}</td>
//拼接编辑的参数,使后台只能获取到当前所选中的id数据,并执行相关操作
<td><a href="/edit?id={{$value.id}}" >编辑</a>
//拼接删除的参数,使后台只能获取到当前所选中的id数据,并执行相关操作
<a href="/del?id={{$value.id}}">删除</a></td>
</tr>
{{/each}}
</tbody>
//结束
</table>
</div>
</div>
</div>
</div>
</body>
</html>
2.添加页面
(1)效果
(2)代码页
(添加页面比较简单,没什么坑,备注就不过多解释了。)
<!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">
<!-- 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="sub-header">添加学生信息</h1>
<div class="table-responsive">
//用post请求提交表单
//用post请求的原因:
//它不会将所有的input中的value值信息都显示在url地址栏中,保护了用户的隐私
<form action="/mes" method="post">
<div class="form-group">
<label for="username">姓名</label>
<input type="text" class="form-control" id="username" name="name" placeholder="用户名">
</div>
<div class="form-group">
<label for="userage">年龄</label>
<input type="text" class="form-control" id="userage" name="age" placeholder="年龄">
</div>
<div class="form-group">
<label>性别</label>
<div>
<input type="radio" name="gender" value="1">男
<input type="radio" name="gender" value="0">女
</div>
</div>
<div class="form-group">
<label for="userhobbit">爱好</label>
<input type="text" class="form-control" id="userhobbit" name="hobbies" placeholder="爱好">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
3.编辑页面
(1)效果图
(2)代码页
<!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">
<!-- Custom styles for this template -->
<link href="../public/css/dashboard.css" rel="stylesheet">
</head>
<body>
<script src="../node_modules/art-template/lib/template-web.js"></script>
<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="sub-header">编辑学生信息</h1>
<div class="table-responsive">
//在/doedit后面拼接参数,方便后台获取对应选中的id数值
//(记得字符串转数据操作)
<form action="/doedit?id={{id}}" method="post">
//下面这行代码被我注掉了,是另一种方法,可以给个样式:hidden,标签隐藏,但实际存在
//用法更加方便,但是我写的时候没有想到,写完才想起来用这个方法 = =
<!--<input type="hidden" name="id" value="{{id}}">-->
<div class="form-group">
<label for="username">姓名</label>
//后台传name值
<input type="text" class="form-control" id="username" name="name" value="{{name}}">
</div>
<div class="form-group">
<label for="userage">年龄</label>
//后台传age值
<input type="text" class="form-control" id="userage" name="age" value="{{age}}">
</div>
<div class="form-group">
<label>性别</label>
//男女用1和0代替
{{if gender == 1 }}
//后台传男/女值
<input id="gender-male" type="radio" checked="true" name="gender" value="1">男
<input id="gender-famale" type="radio" name="gender" value="0">女
{{else if gender == 0 }}
<input id="gender-male1" type="radio" name="gender" value="1" >男
<input id="gender-famale1" type="radio" checked="true" name="gender" value="0">女
{{/if}}
</div>
<div class="form-group">
<label for="userhobbit">爱好</label>
//后台传爱好值
<input type="text" class="form-control" id="userhobbit" name="hobbies" value="{{hobbies}}">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
文件夹
图片是我的路径,可以按照个人的习惯改动.
但是所有的HTML页面必须放在命名为“views”文件夹中,否则网页不能正常运行
- 本地文件路径
- node_moudules的依赖包(灰色文件夹的为我们引入的资源,红色的不用看。)
以上就是我准备的前后端交互例子的全部内容啦,要是有疑问,或者我没有说清楚的地方,可以在下方留言给我,我看到后会第一时间解答,希望与大家一起交流进步~