前言:构建学生系统,用到的技术栈有:express + mongodb + bootstrap + jquery (Ajax)
开发模式:首先ejs模板,前后端不分离
最后ajax,前后端分离。
效果图如下:
一、项目创建
- 创建目录 1909system。
- 打开终端,进入1909system。
- 执行:express -e 1909system
- 进入:cd 1909system
- 安装依赖:yarn install 或者 cnpm install 或者 npm install
- 访问:localhost:3000
二 、环境部署
- 下载bootstrap解压到public
- 下载jquery 放到 public
- 首页index.ejs 引入 bootstrap,和jquery
- 后期下载mongoose, 终端执行: yarn add mongoose -S (–save等同于-S)
<link rel="stylesheet" href="/bootstrap/css/bootstrap.css">
<!-- bootstrap.js 依赖jquery.js ,所有要先引入jquery.js 在进入bootstrap.js-->
<script src="/javascripts/jquery.js"></script>
<script src="/bootstrap/js/bootstrap.js"></script>
三、开发
- 前端页面 index.ejs 中 添加bootstrap中form 模块。
<form action="/api/add" method="post">
<div class="form-group">
<label for="exampleInputEmail1">姓名:</label>
<input type="text" name='user' class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp">
<!-- <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="exampleInputPassword1">年龄</label>
<input type="number" class="form-control" id="exampleInputPassword1" name='age'>
</div>
<div class="form-group">
<label for="">性别</label>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="sex" id="inlineRadio1" value="男">
<label class="form-check-label" for="inlineRadio1">男</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="sex" id="inlineRadio2" value="女">
<label class="form-check-label" for="inlineRadio2">女</label>
</div>
</div>
<button type="submit" class="btn btn-outline-info btn-block">提交</button>
</form>
---------------------------二期展示功能---------------------------
<!-- 数据展示区 table -->
<table class="table table-striped mt-4">
<thead>
<tr>
<th scope="col">姓名</th>
<th scope="col">性别</th>
<th scope="col">年龄</th>
<th scope="col">时间</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<% for(var item in list){ %>
<tr>
<th scope="row"><%= list[item].user %></th>
<td><%= list[item].sex %></td>
<td><%= list[item].age %></td>
<td><%= list[item].updatedAt.toLocaleString() %></td>
<td>
<button>删除</button>
<button>修改</button>
</td>
</tr>
<% } %>
</tbody>
</table>
- 后台接口的定义
-
app.js
var apiRouter = require('./routes/api'); app.use('/api',apiRouter);
-
app.js 连接数据库服务器。
var mongoose =require('mongoose'); mongoose.connect('mongodb://localhost:27017/1909system',function(err){ if(!err){ console.log('数据库服务器连接成功!') } })
-
数据库设计 schema模型、model模型
创建schema目录,创建student.js文件如下:var mongoose = require('mongoose'); //实例化Schema ,创建文档模型 module.exports=new mongoose.Schema({ user:String, age:'number', sex:String },{timestamps:true});
创建model目录。创建Student.js文件如下:
var mongoose = require('mongoose'); var myschema = require('../schema/student'); // 创建model 集合模型。参数一:集合名(数据库中会变成复数形式。) module.exports = mongoose.model('student',myschema);
-
routes 创建 api.js
var express = require('express'); var router = express.Router(); var Student = require('../model/Student') /* 添加 */ router.post('/add', function(req, res, next) { //首先接受数据 post ---> req.body console.log(req.body); //写入数据库。下载mongoose中间件,连接数据库服务器,创建模型设计数据库(schema,model) Student.create({user:req.body.user,age:req.body.age,sex:req.body.sex},function(err){ if(!err){ console.log('写入成功') res.redirect('/'); } }) }); module.exports = router;
-
routes下找到 index.js 修改
var express = require('express'); var router = express.Router(); var Student = require('../model/Student') /* GET home page. */ router.get('/', function(req, res, next) { Student.find({},function(err,datas){ // datas---> [{_id,user,sex,age,createdAt,updatedAt},{},{}...] res.render('index.ejs', { list: datas }); }) }); module.exports = router;
-
四、利用bootstrap模态框删除
- bootstrap官网找到,满足需求的模态框组合。https://v4.bootcss.com/docs/components/modal/#varying-modal-content
- 改造删除按钮
<!-- 开启模态框的button -->
<button type="button" class="btn btn-warning btn-sm" data-toggle="modal" data-target="#exampleModal" data-whatever="<%= list[item]._id %>">删除</button>
- 引入模态框(并且修改)
<!-- 模态框 -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<!-- 头部 -->
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">删除</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<!-- 身体 -->
<div class="modal-body">
<h3>您确定要删除吗?</h3>
</div>
<!-- 底部 -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary del">确定</button>
</div>
</div>
</div>
</div>
- 引入js部分
<script>
//获取模态框,然后绑定事件(show.bs.modal) 该事件当且仅当模态框弹出是触发
$('#exampleModal').on('show.bs.modal', function (event) {
console.log('哈哈,我被弹出了')
var button = $(event.relatedTarget) // Button that triggered the modal 弹出模态框的button
console.log(button);
// 按钮 借助 data-whatever 属性传参过来。
var recipient = button.data('whatever') // 获取button的属性值。data-whatever的属性值。
// If necessary, you could initiate an AJAX request here (and then do the updating in a callback).
// Update the modal's content. We'll use jQuery here, but you could use a data binding library or other methods instead.
console.log(recipient)
var modal = $(this)// 获取当前模态框
// modal.find('.modal-title').text('New message to ' + recipient)
// modal.find('.modal-body input').val(recipient)
// 通过ajax 进行删除
$('.del').on('click',function(){
$.ajax({
url:'/api/del',
type:'get',
data:{_id:recipient},
success:function(res){
console.log(res);
if(res.code==1){ // {code:1,msg:'删除成功'}
// 关闭模态框
modal.modal('hide');
//刷新当前页面
// window.location.href='/'
location.reload()
}
}
})
})
})
</script>
- 后端接口定义
在api.js 中添加 删除接口
/* 删除*/
router.get('/del',function(req,res,next){
console.log(req.query._id)
Student.remove({_id:req.query._id},function(err){
if(!err){
//删除成功
console.log('删除成功');
// ajax 属于异步操作。异步操作 不可以用重定向去相应。
//res.redirect('/')
res.json({code:1,msg:'删除成功'})
}
})
})
五、bootstrap模态框修改
- 复制模态框按钮部分 (改造成自己)
<!-- 开启模态框的 修改 -->
<button type="button" class="btn btn-warning btn-sm" data-toggle="modal" data-target="#update" data-whatever="<%= list[item]._id %>">修改</button>
- 复制模态框部分(改造成自己的)
<!-- 修改模态框 -->
<div class="modal fade" id="update" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<!-- 头 -->
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">修改</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<!-- 体 -->
<div class="modal-body">
<form action="/api/add" method="post">
<div class="form-group">
<label for="user">姓名:</label>
<input type="text" name='user' class="form-control" id="user" aria-describedby="emailHelp">
<!-- <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="age">年龄</label>
<input type="number" class="form-control" id="age" name='age'>
</div>
<div class="form-group">
<label for="">性别</label>
<div class="form-check form-check-inline">
<input class="form-check-input sex" type="radio" name="sex" id="sex1" value="男">
<label class="form-check-label" for="sex1">男</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input sex" type="radio" name="sex" id="sex2" value="女">
<label class="form-check-label" for="sex2">女</label>
</div>
</div>
</form>
</div>
<!-- 脚 -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary update">确认修改</button>
</div>
</div>
</div>
</div>
- 把js 部分拿过来
// 修改
$('#update').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget) // Button that triggered the modal
var recipient = button.data('whatever') // Extract info from data-* attributes
// If necessary, you could initiate an AJAX request here (and then do the updating in a callback).
// Update the modal's content. We'll use jQuery here, but you could use a data binding library or other methods instead.
var modal = $(this)
// modal.find('.modal-title').text('New message to ' + recipient)
// modal.find('.modal-body input').val(recipient)
$('.update').on('click',function(){
//获取最新的user,age,sex
var user=$('#user').val();
var age=$('#age').val();
//sex 获取被选中的单选框的value值,用伪类选择器获取
var sex=$('.sex:checked').val();
console.log(user,age,sex);
$.ajax({
url:'/api/update',
type:'post',
data:{_id:recipient,user:user,age:age,sex:sex},
success:function(res){
console.log(res);
//关闭模态框
if(res.code==1){
modal.modal('hide')
//重载页面
location.reload();
}
}
})
})
})
- 后端 /api/update 接口定义
/* 修改*/
router.post('/update',function(req,res,next){
//接受数据,
console.log(req.body);// {_id:xxxx,user:xxx,age:xxxx,sex:xxxx}
Student.update({_id:req.body._id},{$set:{user:req.body.user,sex:req.body.sex,age:req.body.age}},function(err){
if(!err){
//向前端响应 json数据。 (因为前端 ajax请求)
res.json({code:1,msg:'修改成功'})
}
})
})
六、查询模块
- 前端代码
<!-- 搜索 -->
<form class="form-inline mt-4" action="/" method="get">
<div class="form-group mr-3 mb-2">
<label for="inputPassword2" class="sr-only">Password</label>
<input type="text" name='keyword' class="form-control" id="inputPassword2" placeholder="请输入你要查询的姓名">
</div>
<button type="submit" class="btn btn-outline-info mb-2"> 查询 </button>
</form>
- 后端代码
router.get('/', function(req, res, next) {
var keyword=req.query.keyword||'';// localhost:3000/ /?keyword=小明
//模糊搜索 创建正则。
// var reg=/keyword/;
var reg= new RegExp(keyword);
Student.find({user:reg},function(err,datas){ // datas---> [{_id,user,sex,age,createdAt,updatedAt},{},{}...]
res.render('index.ejs', { list: datas });
})
});
七、分页
- 前端代码
<!-- 分页器 -->
<nav aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item"><a class="page-link" href="/?page=<%= page-1 %>">上一页</a></li>
<% for(var i=1;i<=num;i++){ %>
<% if(page==i){ %>
<li class="page-item active"><a class="page-link" href="/?page=<%= i %>"><%= i %></a></li>
<% }else{ %>
<li class="page-item"><a class="page-link" href="/?page=<%= i %>"><%= i %></a></li>
<% } %>
<% } %>
<li class="page-item"><a class="page-link" href="/?page=<%= page+1 %>">下一页</a></li>
</ul>
</nav>
- 后端代码
var express = require('express');
var router = express.Router();
var Student = require('../model/Student')
/* GET home page. */
router.get('/', function(req, res, next) {
//求总页数,数据的总条数
Student.count(function(err,count){
console.log(count);
// 用户想要第几页的数据
var page=Number(req.query.page)||1
//每页显示几条数据
var limit=2;
//总页数
var num = Math.ceil(count / limit) ;
//每次查询,跳过多少条数据
var skip=(page-1)*limit;
var keyword=req.query.keyword||'';// localhost:3000/ /?keyword=小明
//模糊搜索 创建正则。
// var reg=/keyword/;
var reg= new RegExp(keyword);
Student.find({user:reg}).skip(skip).limit(limit).exec(function(err,datas){
if(!err){
res.render('index',{list:datas,page:page,num:num})
}
})
})
});
module.exports = router;