nodejs
Nodejs内容
博客笔记:01 【nodejs简介】 | dselegent-blog
项目:笔记本
开发过程:
基本结构搭建
1、express -e accounts
2、修改package.json 将node修改成nodemon(可以自动重启)
3、app.js中修改路由 在indexRouter路由界面中添加
// routes\index.js
var express = require('express');
var router = express.Router();
/* 记账本列表 */
router.get('/account', function(req, res, next) {
res.send('账本列表')
});
// 添加记录
router.get('/account/create',function(req, res, next) {
res.send('添加记录')
});
module.exports = router;
相应静态网页
app.js中渲染出index.html页面
/* 记账本列表 */
router.get('/account', function(req, res, next) {
// 渲染模板
res.render('list')
});
添加list页面
// views\list.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link
href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css"
rel="stylesheet"
/>
<style>
label {
font-weight: normal;
}
.panel-body .glyphicon-remove{
display: none;
}
.panel-body:hover .glyphicon-remove{
display: inline-block
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-12 col-lg-8 col-lg-offset-2">
<h2>记账本</h2>
<hr />
<div class="accounts">
<div class="panel panel-danger">
<div class="panel-heading">2023-04-05</div>
<div class="panel-body">
<div class="col-xs-6">抽烟只抽煊赫门,一生只爱一个人</div>
<div class="col-xs-2 text-center">
<span class="label label-warning">支出</span>
</div>
<div class="col-xs-2 text-right">25 元</div>
<div class="col-xs-2 text-right">
<span
class="glyphicon glyphicon-remove"
aria-hidden="true"
></span>
</div>
</div>
</div>
<div class="panel panel-success">
<div class="panel-heading">2023-04-15</div>
<div class="panel-body">
<div class="col-xs-6">3 月份发工资</div>
<div class="col-xs-2 text-center">
<span class="label label-success">收入</span>
</div>
<div class="col-xs-2 text-right">4396 元</div>
<div class="col-xs-2 text-right">
<span
class="glyphicon glyphicon-remove"
aria-hidden="true"
></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
同样添加记录页面也这样渲染出来
ps:在添加记录页面时bug:css和js文件放置在public文件夹下,但是通过相对路径引入时会收到页面url的影响,路径变化会导致相对路径变化,导致它不确定,所有改成绝对路径,它会与域名进行一个拼接。
获取表单数据
在create.js中的表单项中添加name属性,form上添加action属性’/account’ 和method属性 post
同时在index.js中添加新增记录的跳转
// 新增记录
router.post('/account',(req,res) => {
// 获取请求体数据
// 这里打印出来是在控制台下打印 而不是在浏览器中打印
console.log(req.body);
res.send('新增记录')
})
lowdb介绍与使用
lowdb存储数据
npm官网:
主要安装的是lowdb@1.0.0版本
对数据的操作
// test\lowdb.js
// 导入lowdb
const low = require('lowdb')
const FileSync = require('lowdb/adapters/FileSync')
const adapter = new FileSync('db.json')
// 获取db对象
const db = low(adapter)
// 初始化数据
// db.defaults({ posts: [], user:{} }).write()
// 写入数据
// db.get('posts').push({id:1,title:'nice'}).write()
// db.get('posts').push({id:2,title:'trip'}).write()
// 获取数据
// console.log(db.get('posts').value())
// 删除数据
// let res = db.get('posts').remove({id: 1}).write()
// console.log(res);
// 更新数据
let res = db.get('posts').find({id: 2})
res.assign({title: 'nihao!!'}).write()
执行代码:控制台输入
PS D:\accounts\test> node lowdb.js
保存账单信息
使用lowdb版本
// routes\index.js
// 导入lowdb
const low = require('lowdb')
const FileSync = require('lowdb/adapters/FileSync')
// 这里一定要注意生成的db数据的位置 否则容易报错
const adapter = new FileSync(__dirname + '/../data/db.json')
// 获取db对象
const db = low(adapter)
// 新增记录
router.post('/account',(req,res) => {
// 获取请求体数据
// 这里打印出来是在控制台下打印 而不是在浏览器中打印
// console.log(req.body);
// 生成id
let id = shortId.generate()
res.send('新增记录')
// 将获取到的记录写入到db.json中
db.get('accounts').unshift({id:id,...req.body}).write();
})
ps: 这里使用了shortid来表示每条账单的id,需要安装第三方库
npm i shortid
完善成功提醒
添加success页面,成功了之后渲染
添加跳转到首页的连接
// views\success.ejs
<body>
<div class="container">
<div class="h-50"></div>
<div class="alert alert-success" role="alert">
<h1>:) <%= msg %></h1>
<p> <a href="<%= url %>">点击跳转</a></p>
</div>
</div>
</body>
// routes\index.js
// 生成提示
res.render('success',{msg: '添加成功哦!!', url: '/account'})
账单列表
获取到accounts数据之后主要在页面上进行显示 那么需要在模板上进行forEach展示
// views\list.ejs
// 注意这里 <% %>的使用
<div class="accounts">
<% accounts.forEach(item => { %>
<div class="panel <%= item.type === '-1' ? 'panel-danger' : 'panel-success' %>">
<div class="panel-heading"><%= item.time%></div>
<div class="panel-body">
<div class="col-xs-6"><%= item.title%></div>
<div class="col-xs-2 text-center">
<span class="label <%= item.type === '-1' ? 'label-warning' : 'label-success' %>"> <%= item.type === '-1' ? '支出' : '收入' %></span>
</div>
<div class="col-xs-2 text-right"><%= item.account%>元</div>
<div class="col-xs-2 text-right">
<span
class="glyphicon glyphicon-remove"
aria-hidden="true"
></span>
</div>
</div>
</div>
<% }) %>
</div>
删除账单
添加删除路由
// routes\index.js
// 删除记录
// 使用params的参数写法
router.get('/account/:id',(req,res)=> {
let id = req.params.id;
db.get('accounts').remove({id:id}).write()
res.render('success',{msg: '删除成功哦!!', url: '/account'})
})
在模板上的x添加跳转按钮 即点击就跳转到删除路由中
// views\list.ejs
// 给span标签包裹上一个a标签即可
<a href="/account/<%=item.id%>">
<span
class="glyphicon glyphicon-remove"
aria-hidden="true"
>
</span>
</a>
结合数据库
使用mongoose连接mongodb数据库
// connectMongodb.js 只是练习使用与正式项目中的连接有差别
// 1、安装mongoose
// npm i mongoose
// 2、导入
const mongoose = require('mongoose');
// 3、连接mongodb服务
mongoose.connect('mongodb://127.0.0.1:27017/admin');
// 4、设置回调 不用on 推荐用once 只执行一次
mongoose.connection.once('open',()=>{
console.log('连接成功');
})
mongoose.connection.on('error',()=>{
console.log('连接失败');
})
mongoose.connection.on('close',()=>{
console.log('连接关闭');
})
运行时:node connectMongodb.js
拿进数据库的基本操作
在入口文件中连接数据库
// bin\www
// 导入db函数
const db = require('../db/db.js');
// 调用db函数 将原来所有的内容包裹在下方回调函数中
// 含义为:连接上了数据库才能进行项目的运行
db(()=>{ })
创建模型文件
// models\AccountModel.js
//导入 mongoose
const mongoose = require('mongoose');
//创建文档的结构对象
//设置集合中文档的属性以及属性值的类型
let AccountSchema = new mongoose.Schema({
//标题
title: {
type: String,
required: true
},
//时间
time: Date,
//类型
type: {
type: Number,
default: -1
},
//金额
account: {
type: Number,
required: true
},
//备注
remarks: {
type: String
}
});
插入数据库
// routes\index.js
// 使用moment将string类型转换成Date类型
const moment = require('moment');
const AccountModel = require('../models/AccountModel')
// 现在要使用promise的写法
const result = AccountModel.create({
...req.body,
time: moment(req.body.time).toDate()
});
result.then((err) {
res.status(500).send('插入失败')
return;
})
读取数据库
// routes\index.js
// 通过数据库获取到数据
const accounts = AccountModel.find().sort({time: -1})
accounts.then((data) => {
// 渲染模板 且传递参数
res.render('list',{accounts: data, moment: moment})
})
// views\list.ejs
// 对日期做格式化
<div class="panel-heading"><%= moment(item.time).format('YYYY-MM-DD') %></div>
删除数据库
const result = AccountModel.deleteOne({id: id})
result.then((data) => {
console.log(data);
})
结合API
新建routes\account.js 主要用于api访问,然后在app.js中引入
const accountRouter = require('./routes/account.js')
// 使得页面通过api接口可以访问
app.use('/api', accountRouter)
获取账单接口
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 邹阳 の 博客!