node+mongoDb+Vue+elementUI实现资金管理后台
主要内容:
- 构建接口文档:Node+express+jwt;
- 构建前端页面:VueCli 3.0 + Element-Ui;
- 数据请求及拦截:Axios + Robo 3T + MongoDB;
- 数据筛选分页及权限配置
一、确认接口文档
确认需求api,使用express.Router(),分为user和profiles路由:
- 在users.js下写api,即app.use("/api/users",users);
- 注册 “/register”
- 登录 “/login”
- 访问 “/current”
二、确认前端数据信息接口
- 首先导航栏左侧是管理平台名字,右侧为用户头像、欢迎语、用户名,以及下拉框个人信息和退出
- 左侧边栏有三个功能,首页、个人资金流水、个人信息
- 个人资金流水页有表格,时间筛选框、添加信息按钮
- 表格内有操作栏,有编辑和删除按钮
- 分页和跳转功能
- 权限配置(管理者才能使用 删除 键)
三、前后端连载
- 终端合并(前后端打开了两个终端),npm install concurrently
- 修改两个package.json:在后端里添加 :
“clent-install”: “npm install --prefix client” ,
“client” : “npm start --prefix client”,
“dev” : “concurrently “npm run server” “npm run client””, - 使用 npm run dev 即可启动两个终端
四、项目关键步骤
- 安装MongoDB和Robo 3 T(前者的可视化);
打开可视化工具 Robo 3T;
连接数据库:在C:\Program Files\MongoDB\Server\5.0\bin的命令行下
mongod --dbpath D:\MongoDB\data
- 创建node.js基础服务
- 在根目录下创建models/user.js,用来创建user模型(mongoDB表)
module.exports = user = mangoose.model("users",UserSchema);
- express路由:
const router = express.Router();
在路由中的user.js下,设置注册API
• 判断邮箱是否已经注册存在
• 给密码加密,
bcryptjs是一个第三方密码加密库,是对原有bcrypt的优化,优点是不需要安装任何依赖
//1.安装bcryptjs
npm install bcryptjs
//2.引入bcryptjs库
var bcrypt = require('bcryptjs');
//3.使用bcryptjs
添加头像 第三方库
npm i gravatar
使用教程
引入:
const gravatar = require('gravatar');
登录功能,登陆后返回token
• 先设置登录login路径,post请求方法;再从user模型(mongoDB)判断是否存在。
User.findOne({email})
.then(user=>{
密码匹配
// 密码匹配
bcrypt.compare(password, user.password)
.then(isMatch =>{
if(isMatch){
res.json({msg:"sucess"});
}else{
return res.status(400).json({password:"密码错误"})
}
})
使用token
安装 npm install jsonwebtoken
jwt = require('jsonwebtoken');
// jwt.sign("规则","加密名字","过期时间","箭头函数")
jwt.sign(rule,keys.secretOrKey,{expiresIn:3600},(err,token)=>{
if(err) throw err;
res.json({
success:true,
token:"Bearer "+token
})
});
**客户端获取数据,验证token**
在server.js主文件下
const passport = require('passport');
// passpot初始化
app.use(passport.initialize());
验证token
router.get("'/current",passport.authenticate('jwt',{session:false}),(req,res)=>{
res.json({msg:"success"});
})
- 安装vue,在node-app(node项目)文件下,创建vue: vue create client (vue3指令)
- 在前端文件夹client安装element-ui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';
Vue.use(ElementUI);
- 导入axios,http.js文件
http.js文件为axios的请求拦截和响应拦截文件
其中请求拦截:
//请求拦截
axios.interceptors.request.use(config=>{
startLoading();
if(localStorage.eleToken){
//设置统一的请求header
config.headers.Authorization = localStorage.eleToken;
}
return config;
},err=>{
return Promise.reject(err);
})
•在响应拦截中,若token失效,则清除,且重新登录
const {status} = error.response;
if(status == 401){
Message.err('token失效,情重新登录!');
// 清除token
localStorage.removeItem('eleToken');
router.push('/login');
}
7. 跨域解决
devServer: {
open: true,
host: 'localhost',
port: 8081,
https: false,
hotOnly: false,
proxy: { // 配置跨域
'/api': {
target: 'http://localhost:5000/api/',
ws: true,
changOrigin: true,
pathRewrite: {
'^/api': ''
}
}
},
before: app => { }
}
- 安装token解析文件
• cnpm install jwt-decode
• import jwt_decode from 'jwt-decode'
• // 解析token
const decode = jwt_decode(token);
- vuex的使用,两个方面,判断是否登录、存储user信息
// 登录成功
const {token} = res.data;
localStorage.setItem("eleToken",token);
// 解析token
const decode = jwt_decode(token);
//token 存储到vuex中
this.$store.dispatch("setIsAutnenticated",!this.isEmpty(decode));
this.$store.dispatch("setUser",decode)
- 解决浏览器刷新,vuex的store存储的信息消失问题
在根组件App.vue下,浏览器刷新,app.vue会重新加载,在create中获取token,重新将数据存储:
created(){
if(localStorage.eleToken){
//解析token
const decode = jwt_decode(localStorage.eleToken);
//token 存储到vuex中
this.$store.dispatch("setIsAutnenticated",!this.isEmpty(decode));
his.$store.dispatch("setUser",decode)
}
}
原因:vue的store存储在运行内存中,一旦浏览器刷新,会重新加载vue实例,store 也重新赋值
-
在编辑删除框时,我增加了一个删除组件confirm,在foundlist组件下,遇到的问题及解决方式:
• 从父组件得到的数据,在本组件的data中未说明的,使用时要加this.
• 从父组件传来的数据(props),此数据是不能在子组件进行修改的,我在父组件设置子组件显示的变量为Boolean,到了子组件想让其结束后变为false,但是一直报错。解决办法是十七变量为object类型,里面设置一个键值对为Boolean类型,可以修改这个object里面的键值对,不报错。 -
权限配置
- 在computed函数下,得到当前用户的身份:管理员/员工;
computed:{
user(){
return this.$store.getters.user;
}
- 在删除按钮那里,判断,非管理员则禁用按钮
:disabled = "user.identity == 'manager'? false : true"