Node.js - 用户管理系统(简易版)

2,417 阅读9分钟

学习链接

Simple User Management System - Nodejs, Express, MySQL & Handlebars - Raddy

  • 作者:Raddy
  • 日期:2021.02.12

Navicat如何操作数据库

什么是handlebars?

学习目标

技术栈:express、mysql、handlebars。

前端搭建页面,使用handlebars模板引擎,结合bootstrap一起实现展示页面,具体的实现功能有:

  • 搜索用户信息 - 结合路由,返回数据库内容
  • 删除用户信息
  • 创建用户信息
  • 修改用户信息

后端利用express的路由信息进行管理,和mysql进行交互,完成对于用户的增删改查功能的实现。

搭建流程

系统的具体实现,可以分为五个步骤

  1. 数据录入 - mysql数据库的创建!
  2. 搭建环境 - node.js环境和数据库信息输入
  3. 配置路由 - 路由信息以及数据连接
  4. 创建页面 - handlebars编写页面以及bootstrap框架
  5. 增删改查 - 用户信息修改、删除、查找、增加!

系统实现

1. 数据录入

使用的软件是navicat,点击查询,输入sql语句,点击运行,创建项目所需的表!

image.png

输入内容

  • 它会在mysql数据中,创建usermanagement_tut表,以及其中的字段信息!
CREATE TABLE `mysql`.`usermanagement_tut` (
	`id` INT NOT NULL AUTO_INCREMENT,
	`first_name` VARCHAR (45) NOT NULL,
	`last_name` VARCHAR (45) NOT NULL,
	`email` VARCHAR (45) NOT NULL,
	`phone` VARCHAR (45) NOT NULL,
	`comments` TEXT NOT NULL,
	`status` VARCHAR (10) NOT NULL DEFAULT 'active',
	PRIMARY KEY (`id`)
)

还有表中的值,同样写入表中

INSERT INTO `usermanagement_tut` 
(`id`, `first_name`,  `last_name`,    `email`,                 `phone`,         `comments`, `status`) VALUES
(NULL, 'Amanda',      'Nunes',        'anunes@ufc.com',        '012345 678910', '',          'active'),
(NULL, 'Alexander',   'Volkanovski',  'avolkanovski@ufc.com',  '012345 678910', '',          'active'),
(NULL, 'Khabib',      'Nurmagomedov', 'knurmagomedov@ufc.com', '012345 678910', '',          'active'),
(NULL, 'Kamaru',      'Usman',        'kusman@ufc.com',        '012345 678910', '',          'active'),
(NULL, 'Israel',      'Adesanya',     'iadesanya@ufc.com',     '012345 678910', '',          'active'),
(NULL, 'Henry',       'Cejudo',       'hcejudo@ufc.com',       '012345 678910', '',          'active'),
(NULL, 'Valentina',   'Shevchenko',   'vshevchenko@ufc.com',   '012345 678910', '',          'active'),
(NULL, 'Tyron',       'Woodley',      'twoodley@ufc.com',      '012345 678910', '',          'active'),
(NULL, 'Rose',        'Namajunas ',   'rnamajunas@ufc.com',    '012345 678910', '',          'active'),
(NULL, 'Tony',        'Ferguson ',    'tferguson@ufc.com',     '012345 678910', '',          'active'),
(NULL, 'Jorge',       'Masvidal ',    'jmasvidal@ufc.com',     '012345 678910', '',          'active'),
(NULL, 'Nate',        'Diaz ',        'ndiaz@ufc.com',         '012345 678910', '',          'active'),
(NULL, 'Conor',       'McGregor ',    'cmcGregor@ufc.com',     '012345 678910', '',          'active'),
(NULL, 'Cris',        'Cyborg ',      'ccyborg@ufc.com',       '012345 678910', '',          'active'),
(NULL, 'Tecia',       'Torres ',      'ttorres@ufc.com',       '012345 678910', '',          'active'),
(NULL, 'Ronda',       'Rousey ',      'rrousey@ufc.com',       '012345 678910', '',          'active'),
(NULL, 'Holly',       'Holm ',        'hholm@ufc.com',         '012345 678910', '',          'active'),
(NULL, 'Joanna',      'Jedrzejczyk ', 'jjedrzejczyk@ufc.com',  '012345 678910', '',          'active')

表格创建完毕,共有六个字段

  • id - 唯一id
  • first_name - 名
  • last_name - 姓
  • email - 邮箱
  • phone - 电话
  • comments - 评论
  • status - 状态

表格信息展示,用于程序获取、修改等

image.png

2. 搭建环境

初始化项目

  • 创建一个文件夹,输入 npm init -y,得到package.json

安装所需的库

  • npm install mysql express dotenv express-handlebars

配置scripts属性 image.png

创建app.js文件

image.png

app.js中的内容

image.png

**启动项目命令 **

  • npm run start
  • 启动项目,并且开始监听5000端口

image.png

app.js中的完整内容

image.png

补充信息:

3. 配置路由

配置路由是案例的核心内容,通过对不同路由的响应,展示对应的内容,数据的传递,也是通过路由信息来实现的。

在app.js文件中,我们配置了app.use("/", routers),所有在根路径(/)下的路由,都会通过routers进行处理。

创建server文件夹,以及routes文件夹和controllers文件

  • 在routes文件下的user.js处理路由信息的跳转
  • 在controllers文件下的userController.js处理路由信息的数据传递
  • 它们的关系是user.js引入userController.js,做到了路由信息和数据信息的分离

image.png

user.js中的内容

  • 这里的router.get("/", userController.view),对应localhost:5000/
  • 这里的router.get("/adduser", userController.view),对应localhost:5000/adduser
  • 它们的根路径,在app.js中设置了,即/
  • 处理路由的内容,都放在userController里,
  • 在user.js中,主要就是处理get 和post请求,分配路由信息

image.png

userController.js中的内容

  • 连接mysql数据库
  • 根据路由信息,处理不同的功能,
  • 这里的exports.view,将获取到的信息(数据库查表),展示到页面上!共做了两步操作
    1. 查询语句SELECT * FROM usermanagement_tut WHERE status = 'active'
    2. 页面渲染res.render("home", {rows, removedUser});,这是用handlebars模板写的home页面,利用res.render将home页面渲染到页面中,同时也将找到的数据传递到模板中,实现了页面的更新!

image.png

其他功能,在后文 增删改查中详述。

4. 创建页面

main.hbs

利用handlebars创建页面,我们创建views文件夹,接着创建layouts文件夹以及main.hbs,这是页面渲染的入口

image.png

写个hello image.png

页面显示出来了!

image.png

在main.hbs中引入bootstarp组件,

  • 共三个,bootstrap样式,bootstrap图标,bootstrap的js文件
<link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
      crossorigin="anonymous"
    />
<link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.3.0/font/bootstrap-icons.css"
    />
<script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
      crossorigin="anonymous"
    ></script>

在bootstrap官网,选个nav导航栏组件

image.png

修改一下样式,修改跳转路由,这样可以将请求的数据拦截,在这个过程中,获取后端数据!

image.png

目前效果

image.png

在main.hbs中输入{{{body}}}(三个括号),它存放的是home.hbs的内容。这样页面的入口的和其他页面就分离了!

image.png

在home.hbs中写入hello...

image.png

页面效果,组件分离!

image.png

home.hbs

home.hbs写了三个样式

  1. 提示信息 - (删除用户信息时候提示)
  2. 添加按钮 - (跳转到添加用户页)
  3. 展示列表 - (列表展示,后台获取信息)

image.png

  1. 提示信息

handlebars模板引擎使用render函数进行渲染,在渲染的同时,可以传递信息,实现页面的动态展示!

image.png

  1. 添加按钮

添加用户按钮,点击跳转到对应的页面(同时渲染在浏览器中)

image.png

  1. 展示列表

image.png

add-user.hbs

共三个部分

  1. 导航信息 - 用于返回主页
  2. 提示信息 - 添加成功显示!
  3. 用户表单 - 使用user-form.hubs,复用同样页面

submit按钮的跳转路由是 /adduser,express会对提交的信息做处理(写入数据库)

image.png

image.png

user-form.hbs

可以复用的页面,放在partials下!

image.png

user-form.hbs内容

image.png

edit-user.hbs

image.png

同add-user.hbs,不过传入当前用户的信息!会在user-form.hbs中显示!(这里的this就派上用场了! - this.first_name!)

image.png

view-user.hbs

展示用户信息!

image.png

image.png

5. 增删改查

有了页面,那么页面中的数据是怎么传入的呢?

  • 当我们跳转到对应的路由,会利用express的中间件(app.use),处理请求和响应之间的数据
  • 在这个过程中,根据发送请求的路由信息,获取对应的数据内容,然后渲染对应的handlebars模板(比如main.hbs, home.hbs, add-user.hbs等),同时传入我们获取到的数据,就实现了页面的动态展示
  • 使用handlebars模板引擎的好处
    • 增加页面的复用性 - 页面拆分
    • 可以使用条件、循环等语句 - 页面展示逻辑
    • 连接了前端和后端信息,直接渲染出来 - 不需要处理dom

好,再来梳理一下路由的交互方式

在app.js中,当我们访问根目录时,会执行routes方法(这里放着我们处理的路由信息)

image.png

处理路由的方式

-image.png

  • 将路由分为两个部分,一个负责处理请求路由,一个负责响应路由(渲染页面 + 传递数据库信息)
  • user.js - 处理请求路由
  • userController.js - 负责响应路由

user.js内容

  • 引入userController.js,处理请求信息

image.png

路由与交互行为分析!

  • 路由的跳转,与用户的行为(事件)密不可分!
  • 这里的路由信息,并不遵循restful api(资源),更多的是语义化的路由信息
// 获取所有信息 -(在home页面,列表展示 - 页面初始化!)
router.get("/", userController.view); 

// 搜索框 输入信息,发起post请求
router.post("/", userController.find); 

// 点击添加按钮(跳转页面到user-add.hbs,开始创建)
router.get("/adduser", userController.form); 

// 点击提交按钮(创建完毕)
router.post("/adduser", userController.create); 

// 点击修改按钮(跳转页面到user-edit.hbs,开始修改)
router.get("/edituser/:id", userController.edit); 

// 点击提交按钮(修改完毕)
router.get("/edituser/:id", userController.update); 

// 点击用户展示按钮 - (跳转页面到view-user.hbs,展示当前用户的所有信息)
router.get("/viewuser/:id", userController.viewall); 

// 点击删除按钮 - (删除当前用户,并给出提示信息)
router.get("/:id", userController.delete);

相关学习资料:

get 和 post学习链接

  • GET/POST 请求区别详解(接口测试实战) - 腾讯云开发者社区-腾讯云 (tencent.com)
  • get请求
    • get请求显示在url上,不安全
    • 有长度限制
    • 请求数据会完整留在历史记录里
    • 只能进行url编码
    • 被浏览器主动cache(缓存)
  • post请求
    • 请求信息在request body中
    • 长度没有限制
    • 相对于get来说,安全一点(http中,都是明文显示)
    • post的参数,不会留在历史记录里
    • 支持多种编码方式
    • 浏览器不会主动cache
  • HTTP协议中的两种发送请求的方法,本质是TCP连接
  • GET产生一个TCP数据包(全部);POST产生两个TCP数据包(先发送header,再发送data)

node js中的req.body,req.query,req.params取参数 - Diamond蚊子 - 博客园 (cnblogs.com)

  • 获取get路由信息 - req.params.userid
  • 获取post信息 - req.body.search
  • req.params包含路由参数(在URL的路径部分),而req.query包含URL的查询参数(在URL的?后的参数)。

mysql模糊查询

详细分析下,每个路由的执行内容

userController.view

home.hbs,获取所有列表信息

image.png

userController.find

头部导航栏,输入框,输入名 或姓,查找信息,由home.hbs列表呈现

image.png

userController.form

返回add-user.hbs添加用户页面!不需要查询数据库

image.png

userController.create

将所有的表单数据,插入(INSERT)到数据库

image.png

userController.edit

通过url获取需要修改的用户的id信息,从数据库获取该用户的所有信息

image.png

userController.update

继续由edit-user页面展示,并发送修改成功的信息

共做两步操作

  1. 使用UPDATE,更新数据信息
  2. 使用SELECT,获取最新数据

image.png

userController.viewall

获取当前用户的所有信息,SELECT查询url中的id即可

image.png

userController.delete

删除用户,通过状态来控制,这样即保留了用户,又不会显示在页面中!删除成功,重定向,会再次获取全部信息。

image.png

image.png

总结

记完整录了前后交互过程,对于前端路由和后端路由有了进一步的理解。

前端路由主要通过get和post来传递数据,后端路由通过拦截前端路由的数据,进行处理后,再返回给前端展示。

后端路由更多的涉及到用户行为和数据的关系。点击什么按钮,返回什么数据,还需要考虑到api的设计,如何处理get和post方法。

原作者其他关于node的教程,也非常棒!多多关注!

你是最好哒最俏哒 最妙哒最骄傲哒!