Vue3_Project更新中

Vue-Cli3 + Node Project

项目展示以及技术栈

NodeJS构建后端接口 VueCli3.0构建前端页面

  1. 构建接口文档:Node + express + jwt
  2. 构建前端页面:VueCli3.0 + Elemenet-ui
  3. 数据请求及拦截 : Axios + Mlab + MongoDB
  4. 分页和筛选
  • 可以掌握的技能点:
    • 全站开发的项目经验
    • 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 就可以了

    • 然后是 为了 不一直重启 所以就 安装 nodemoncnpm 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
  • 进入之后 有一个 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
    })
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容