Vue-Cli3 + Node Project
项目展示以及技术栈
NodeJS构建后端接口 VueCli3.0构建前端页面
- 构建接口文档:Node + express + jwt
- 构建前端页面:VueCli3.0 + Elemenet-ui
- 数据请求及拦截 : Axios + Mlab + MongoDB
- 分页和筛选
- 可以掌握的技能点:
- 全站开发的项目经验
- Token处理
- 请求和响应拦截
- 组件封装
Node 接口搭建
express 搭建服务器
-
cd到项目文件夹下 初始化一个 package.json
-
npm init
会让选择名字 描述:restful api - 入口文件的名字 默认index.js 也可以更换名字
- 然后一路回车就可以了
-
cttl + ~
可以打开 这个 VSCode 的 npm 控制台touch server.js
然后就创建了一个server.js
的文件-
借助
express
框架搭建我们的 服务器安装
npm install express -S
-
然后 具体在
server.js
中的代码如下:const express = require("express"); const app = express(); app.get("/",(req,res) => { res.send("Hello World~"); }) // 端口号 const port = process.env.PORT || 5000; app.listen(port,() => { console.log(`Server running on port ${port}`); })
然后
node server.js
就可以了-
然后是 为了 不一直重启 所以就 安装 nodemon
cnpm i nodemon -G
然后nodemon server.js 就可以了
-
然后在
package.json
里面可以设置:"script" : { "start" : "node server.js", // 上传上线的时候 会有一个 start "server" : "nodemon server.js" // 这个是本地测试的时候启动的 }
-
然后运行
npm run start
就可以运行了- 这种情况下 就是 每次写完代码就需要重启
- 然后在开发环境下的话 运行
npm run server
就可以了
连接MongoDB 数据库
mLab部分
-
在这个项目课程当中 连接的就是 线上的 mLab mongodb 数据库
然后注册完成后 会给一个 500M 的使用权(个人开发完全够用)
-
新建的时候 选择
amazon
然后选择SANDBOX
然后CONTINUE
- 然后选择 区域 美国 US East 然后设置名字 点击
CONTINUE
点击SUBMIT
- 然后选择 区域 美国 US East 然后设置名字 点击
进入之后 有一个
Users
创建 不勾选Make read-only
然后 就可以看到 上面有一个 mongodb 的地址了 这个地址就可以存储和读取数据了
接下来是代码部分
-
下载一个
cnpm install mongoose -S
在
server
下面引入mongoose// server.js文件下的内容 const mongoose = require("mongoose"); // DB config 如果是本地的就是本地的URI不是就是网络的 const db = require("./config/keys").mongoURI; // Connect to mongodb 提供了promise提供了.then mongoose.connect(db) .then( ()=>console.log("MongoDB Connected") ) .catch( err=>console.log(err) )
-
在根目录下面创建一个文件夹
config
创建一个keys.js
// keys.js下面的内容 module.exports = { mongoURI : "就是刚刚mLab复制的地址" // 里面的user和password 更改为自身创建的mLab账号密码 }
搭建接口 - 路由和数据模型
-
根目录创建文件夹
routes
里面新建一个api
文件夹 新建一个users.js
// users.js文件下的内容 // @login & register const express = require("express"); const router = express.Router(); // $route GET api/users/test // @desc 返回请求的json数据 // @access public router.get("/test",(req,res) => { res.json({msg:"login works"}) // 这个就是向浏览器返回一个json数据 }) module.exports = router;
-
然后再
server.js
中补充添加路由相关的引用// 引入user.js const users = require("./routes/api/users") // 使用 routes 在端口号下面 添加使用中间件 app.use("/api/users",users)
-
然后创建一个
modules
的文件夹 在下面创建一个User.js
的文件// User.js const mongoose = require("mongoose"); const Schema = mongoose.Schema; // Create Schema const UserSchema = new Schema({ name : { type : String, required : true }, email : { type : String, required : true }, password : { type : String, required : true }, avatar : { // 头像 type : String }, date : { type : Date, default : Date.now } }) module.exports = User = mongoose.model("users",UserSchema);
搭建注册接口并存储数据
本地测试接口的一个工具
注册接口
第三方头像的一个库
测试本地接口的一个工具
postman
进入官网下载app然后进行 注册登录
在
Get
之后的URL
中 输入后台调试的接口地址。-
搭建一个 注册 接口
// users.js // $route POST api/users/register // @desc 返回请求的json数据 // @access public router.post("/register",(req,res) => { console.log(req.body); }) // 如果要使用 post 请求 就需要安装 body-parser
-
然后在
server.js
注册引入就好啦const bodyParser = require("body-parser"); // 然后使用一个body-parser的中间件 app.use(bodyParser.urlencoded({extended:false})); app.use(bodyParser.json()); // 然后回到 users.js
-
这样在 postman 里面就有然后选择类型 post
然后选择 body 里面的 x-www-form-urlencoded 然后在 Header 里面就会自动添加
在 Body里面 key里面 添加数据
key(email)
然后再value里面 添加数据values(test@test.com)
然后
send
发送就可以了 在node
里查看就可以了~( console.log(req.body) )// users.js下面内容 const User = require("../../models/User"); const bcrypt = require("bcrypt") router.post("/register",(req,res) => { // 查询数据库中是否拥有邮箱 User.findOne({email : req.body.email}) .then((user) => { //然后就会返回一个 user if(user){ return res.status(400).json({ email : "邮箱已经被注册" }) } else { // 第一个参数要展示的是 email 所以直接设置成 req.body.email // s 就是size r 就是选择图片的格式 d 404会报错 mm 会显示一个头像 // 如果是在 gravatar 中已经注册过的用户 就可以拥有属于自己的头像 const avatar = gravatar.url(req.body.email, {s: '200', r: 'pg', d: 'mm'}); const newUser = new User({ // newUser进行一个存储 name : req.body.name, email : req.body.email, avatar, // 在es6中相同的名字写一个就可以了 password : req.body.password // 需要对当前密码进行加密 }) // saltRounds这是一个加密模式 改为 10就可以了 // myPlaintextPassword 这就表示 这个是要对谁进行加密 bcrypt.genSalt(10, function(err, salt) { bcrypt.hash(newUser.password, salt, function(err, hash) { // 加密成功的话 就会返回返回一个加密的函数 if(err) throw err; newUser.password = hash; newUser.save() .then( user => res.json(user) ); // 如果存储成功就会返回一个 user .catch( err => console.log(err) ); }); }); } } ) })
-
需要对当前密码进行加密
- 然后需要安装一个
npm install bcrypt
- 然后在什么地方需要安装一个加密 就引入加密就可以了 代码在上面的
- 然后需要安装一个
然后点击
postman
进行测试 输入 账户密码邮箱 等等 然后就可以进行验证 就存入mongodb
里面然后 mLab 里面进行相对应查看就可以了
全球公认头像gravatar
-
安装
cnpm i gravatar -S
然后在
users,js
中引入const gravatar = require('gravatar'); // 然后具体代码 在上面例子中会显示。
搭建登录接口
// users.js 页面下的内容
// $route POST api/users/login
// @desc 返回token 会用到 jwt passport
// @access public
router.post("/login",(req,res) => {
const email = req.body.email;
const password = req.body.password;
// 查询数据库
User.findOne({email})
.then(user => {
if(!user){
return res.status(404).json({email:"用户不存在"});
}
// 密码匹配
// myPlaintextPassword就是获取的密码
// hash 获取到数据库里面user下面的一个 password
// bcrypt。compare(password,user.password,function(err,res){
// // res == true
// })
bcrypt。compare(password,user.password)
.then(isMatch => {
if(isMatch){
// jwt.sign("规则","加密名字","过期时间","箭头函数");
const rule = {id:user.id,name:user.name};
jwt.sign(rule,keys.secretOrKey,{expiresIn:3600},(err,token)=> {
if(err) throw err;
res.json({
success : true,
token : "gl " + token // 这样这里返回的就是 gl+规则的一个值啦
});
});
// res.json({msg:"success"}) // 这个地方之后会返回一个 token
}else{
return res.status(400).json({password:"密码错误"});
}
// 然后在 postman 中测试的时候就可以进行相对应的测试
})
})
})
Node接口搭建 - 使用jwt实现token
-
安装第三方包
cnpm i jsonwebtoken -S
const jwt = require('jsonwebtoken'); // 然后具体代码 在上面有写入 在写jwt 的 secretOrKey 的时候在keys.js中定义暴漏一下 const keys = require('../../config/keys'); // keys.js 内容如下 { secretOrKey : "secret" }
Node接口搭建 - 使用passport验证token
-
token
相当于是一个令牌 拿着令牌去请求对应的数据库的信息 如果没有token 或者 token过期的就得不到数据了
// user.js 页面内容 // $route GET api/users/current 这里是假定用户已经拿到对应的数据啦 然后是想要请求信息 // @desc return user // @access Private // router.get("/current","验证token",(req,res)={}) router.get("/current",,(req,res)={ res.json({msg : "success"}); })
安装
cnpm i passport passport-jwt -S
-
引入 passport 在server中引入
// server.js const passport = require("passport"); // passport 的初始化 一定要进行初始化 app.use(passport.initialize()); // 引入文 passport单独写在一个文件夹中 (passport)这个是传递过去的一个 passport require("./config/passport")(passport); // poassport.js 内容如下: const JwtStrategy = require('passport-jwt').Strategy, ExtractJwt = require('passport-jwt').ExtractJwt; const mongoose = require("mongoose"); // 引入他的原因就是需要用到 user.js const User = mongoose.model("users"); const keys = require('../config/keys'); // opts 是当前的配置信息 const opts = {} opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken(); opts.secretOrKey = 'keys.secretOrKey;
前后端连载的模块 concurrently
将多个终端启动的项目进行绑定 然后一次性进行启动构建
cnpm install concurrently -S
-
然后进行相关的配置
在根目录下面的 package.json 来进行配置
// 前端构建页面的 package.json { "serve" : "vue-cli-service serve", "build" : "vue-cli-service build", "start" : "npm run serve" // 这里是将 serve 进行启动使用的是 npm start 命令 } // 后端构建的package.json 里面进行构建 { // 首先确定了 前端 已经依赖了这里的模块 格式就是 : 前端项目名称-install "client-install" : "npm install --prefix client", // 当启动的时候 首先安装client的依赖模块 // npm start 就会启动当前前端页面的项目 然后 --prefix 会告知启动的路径 "client" : "npm start --prefix client", "start" : "node server.js", "server" : "nodemon server.js", // 接下来就是要启动 连载的项目 npm run client/server 就会启动前端/后端项目 接下来进行绑定构建 "dev" : "concurrently \"npm run server\" \"npm run client\"" // 然后就可以进行 一次性启动 来启动前后端项目连载的过程了 }
路由守卫
-
只能访问 注册和的登录页面其他的页面都访问不了 这就是路由守卫
// router.js 下的内容 // 路由守卫 router.beforEach((to,form.next)=>{ // 即使判断 lg 中是否拥有 token 拥有的话 就是登录状态 const isLogin = localStorage.eleToken ? true : false; if(to.path == '/login' || to.path == '/register'){ next(); } else { isLogin ? next() : next('/login'); } });
// http.js 下的内容 // 请求拦截 axios.interceptors.request.use( config => { // 加载动画 startLoading(); if(localStorage.eleToken) { // 设置统一的请求 header config.header.Authorization = localStorage.eleToken; } return config; } ) // 响应拦截 // 看一下当前的状态码是不是401 如果是401说明token已经失效了 然后将ls中的token删除 axios.interceptors.response.use( response => { // 结束加载动画 endLoading(); return response; }, error => { // 错误提醒 endLoading(); Message.error(error.response.data); // 获取错误状态码 const { status } => error.response; if(status == 401){ Message.err("token失效,请重新登录~"); // 清楚token localStorage.removeItem('eleToken'); // 跳转到登录页面 router.push('/login'); } return Promise.reject(error); } )
解析token数据 并且 存储到 vuex 里面
-
需要安装一个 解析 token 的模块
cnpm install jwt-decode -S
import jwt_decode from 'jwt-decode'; submitForm(formName){ ... // 存储到 ls localStorage.setItem('eleToken',token); // 解析 token const decoded = jwt_decode(token); console.log(decoded); ... }
然后将解析的内容进行一个存储 存储到
vuex
中// store.js下的内容 import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const types = { SET_AUTHENTICATED : "SET_AUTHENTICATED", //判断是否认证通过 SET_USER : "SER_USER" } const state = { isAuthentivated : false, // 是否授权 user : { // 会将信息保存到user这个状态中去 } } const getters = { } const mutations = { } const actions = { } export default new Vuex.Store({ state, getters, mutations, actions })