• vue+mongodb+nodejs实现表单增删改查


    Express+Mongodb+Vue实现增删改查

    效果图

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    前言

    最近一直想学下node,毕竟会node的前端更有市场。但是光看不练,感觉还是少了点什么,就去github上看别人写的项目,收获颇丰,于是准备自己照葫芦画瓢写一个。

    作为程序员,一定要保持不断学习的状态,这样我们才可以在职场中有一席之位。

    学习vue,你会知道除了jQuery这种结构驱动(操作dom元素)外,还有更加便捷的数据驱动,妈妈再也不用担心我忘记jQuery中那些可怕的选择器了。学习node,你会知道除了java、c、python这些陌生的后台语言外,js既然也可以写后台,你可以定义自己的接口,不在依赖于那些后台糙汉子。学习mongodb,你会知道数据如何存储在数据库中,已经如何进行增删改插。

    开发环境

    本地需要安装mongodb、nodejs、vue-cli(脚手架)

    第一步:初始化项目

    通过vue-cli脚手架,我们可以快速搭建一个项目骨架。

    vue init webpack my-project
    
    cd my-rpoject && npm install
    
    cnpm run dev
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果在终端,你看到了下图所示,表示项目已经成功启动。接着在浏览器地址栏中输入localhost://8080,如果你看到了vue的欢迎界面,表示你已经完成了第一步。

    在这里插入图片描述

    第二步:把本地的mongodb启动起来

    前提:下载mongodb,并且已经配置好了环境变量。

    如果觉得配置环境变量啥麻烦的话,可以用homebrew进行一键安装。

    当上述都ok的情况下,你只要进入到mongodb的安装目录(比如我的mongodb安装在/usr/local/bin/目录下)执行mongo命令,如果你看到下图所示,表示你已经完成了第二步。

    在这里插入图片描述

    第三步:把后台接口写好

    提示:所谓的后台接口,就是通过express建立路由,如果不明白的话可以去看下express介绍express官网

    express官网: https://www.expressjs.com.cn/

    前提:通过npm安装expressmongoosebody-parser模块

    express模块用来创建路由 mongoose模块用来创建数据库,连接数据库 body-parser模块用来对post请求的请求体进行解析

    //通过命令行进入项目,执行以下命令安装这三个模块
    cnpm install express body-parser mongoose --save
    
    • 1
    • 2

    在项目根目录建立个app.js文件,用来启动express服务

    //app.js文件
    
    //1.引入express模块
    const express = require('express')
    //2.创建app对象
    const app = express()
    //定义简单路由
    app.use('/',(req,res) => {
      res.send('Yo!')
    })
    //定义服务启动端口
    app.listen(3000,() => {
        console.log('app listening on port 3000.')
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    上述步骤走完后,在命令行执行node app.js。通过浏览器访问localhost:3000,页面出现res.send()的内容即表示成功。

    第四步:创建数据模型

    提示:所谓的数据模型,可以理解为你将来创建的表中,要存什么样的数据片段,数据类型是什么。

    在项目根目录建立一个models文件夹,用来存储数据模型,每个模型都是由一个Schema生产,具体的我们不用太在意,如果有兴趣可自行百度。

    models文件夹中创建一个hero.js文件,内容如下

    //hero.js文件
    
    //引入mongoose模块
    const mongoose = require('mongoose')
    
    //定义数据模型,可以看到,我们下面创建了一个表,表中的数据有name、age、sex等字段,并且这些字段的数据类型也定义了,最后将model导出即可
    const heroSchema = mongoose.Schema({
      name :String,
      age : String,
      sex : String,
      address : String,
      dowhat : String,
      imgArr:[],
      favourite:String,
      explain:String
    }, { collection: 'myhero'})
    //这里mongoose.Schema最好要写上第二个参数,明确指定到数据库中的哪个表取数据,我这里写了myhreo,目的就是为了以后操作数据要去myhreo表中。
    这里不写第二个参数的话,后面你会遇到坑。
    
    //导出model模块
    const Hero = module.exports = mongoose.model('hero',heroSchema);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    第五步:建立CURD(增删改查)路由接口

    在项目根目录创建一个router文件夹,文件夹中创建一个hero.js文件,内容如下,分别为增删改查、添加图片等路由

    //引入express模块
    const express = require("express");
    //定义路由级中间件
    const router = express.Router();
    //引入数据模型模块
    const Hero = require("../models/hero");
    
    // 查询所有英雄信息路由
    router.get("/hero", (req, res) => {
      Hero.find({})
        .sort({ update_at: -1 })
        .then(heros => {
          res.json(heros);
        })
        .catch(err => {
          console.log(2);
          res.json(err);
        });
    });
    
    // 通过ObjectId查询单个英雄信息路由
    router.get("/hero/:id", (req, res) => {
      Hero.findById(req.params.id)
        .then(hero => {
          res.json(hero);
        })
        .catch(err => {
          res.json(err);
        });
    });
    
    // 添加一个英雄信息路由
    router.post("/hero", (req, res) => {
      //使用Hero model上的create方法储存数据
      Hero.create(req.body, (err, hero) => {
        if (err) {
          res.json(err);
        } else {
          res.json(hero);
        }
      });
    });
    
    //更新一条英雄信息数据路由
    router.put("/hero/:id", (req, res) => {
      Hero.findOneAndUpdate(
        { _id: req.params.id },
        {
          $set: {
            name: req.body.name,
            age: req.body.age,
            sex: req.body.sex,
            address: req.body.address,
            dowhat: req.body.dowhat,
            favourite: req.body.favourite,
            explain: req.body.explain
          }
        },
        {
          new: true
        }
      )
        .then(hero => res.json(hero))
        .catch(err => res.json(err));
    });
    
    // 添加图片路由
    router.put("/addpic/:id", (req, res) => {
      Hero.findOneAndUpdate(
        { _id: req.params.id },
        {
          $push: {
            imgArr: req.body.url
          }
        },
        {
          new: true
        }
      )
        .then(hero => res.json(hero))
        .catch(err => res.json(err));
    });
    
    //删除一条英雄信息路由
    router.delete("/hero/:id", (req, res) => {
      Hero.findOneAndRemove({
        _id: req.params.id
      })
        .then(hero => res.send(`${hero.title}删除成功`))
        .catch(err => res.json(err));
    });
    
    module.exports = router;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93

    最后将路由应用到app.js(也就是在app.js文件中引入上述路由定义)

    //app.js文件
    
    ......
    //引入刚才定义的hero路由
    const hero = require('./router/hero')
    ......
    app.use('/api',hero)
    ......
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这时你可以通过Postman(模拟http请求数据软件)进行查询测试,如果可以查询到数据,代表后台接口已经成功写好了

    注意:在查询之前,你要简单学习下mongodb如何向数据库中对应的表里面任意添加一条数据,否则,你查询出来的数据为空!!!

    比如我上面创建了一个myhero表,那我在执行上面查询之前,我会往表中添加一条模拟数据

    在这里插入图片描述

    //db.myhero.insert意思就是向数据库中表名为myhero的表中添加一条数据
    db.myhero.insert({
        "imgArr" : [ 
            "http://ossweb-img.qq.com/images/lol/web201310/skin/big157000.jpg", 
            "http://ossweb-img.qq.com/images/lol/web201310/skin/big157001.jpg", 
            "http://ossweb-img.qq.com/images/lol/web201310/skin/big157002.jpg",    
        ],
        "name" : "亚索",
        "age" : "22",
        "sex" : "man",
        "address" : "德玛西亚",
        "dowhat" : "中单、刺客",
        "favourite" : "死亡如风常伴吾身",
        "explain" : "亚索是一个百折不屈的艾欧尼亚人,也是一名身手敏捷的剑客,能够运用风的力量对抗敌人。年少轻狂的他曾为了荣誉而一再地损失珍贵的东西,他的职位、他的导师、最后是他的亲兄弟。他因无法摆脱的嫌疑而身败名裂,如今已是被人通缉的罪犯。亚索在家园的土地上流浪,寻找对过去的救赎。苍茫间,只有疾风指引着他的利剑。",
        })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    这里进行数据库操作,可以在终端中进行,也可以下载可视化工具Robo 3T(链接地址)进行操作,会更加方便。

    好了,到这里我们整个功能的复杂部分已经实现。我们回顾下做了哪些准备工作

    1. vue-cli初始化项目
    2. 启动本地mongodb服务
    3. 将后台接口路由写好app.js文件
    4. 创建我们存放数据的数据模型heroSchema.js文件
    5. 写好增删改查路由接口hero.js文件

    一鼓作气,接下来就是我们擅长的前端部分了。现在的你可以稍微松口气了。是不是觉得很刺激,很过瘾~

    第六步:选择前端开发必要模块

    提示:这里可以自由发挥,我下载的模块中有elementvue-resource。建议你跟我使用同样的模块,避免后期不必要麻烦,等你回过头来对整个项目了然于心的时候,就可以随心所欲的选择你要用的技术了,

    //element-ui是饿了么为我们前端开发者提供的组件化框架,拿来就可以用。好用到没朋友。vue-resource是用来处理请求的,不过vue2.0后好像出现了个axios,不在维护vue-resource,不过我之前一直用vue-resource的,很方便,现在也可以用。
    cnpm install element-ui vue-resource --save
    
    • 1
    • 2

    第七步:建立首页和详情页组件

    src/components路径下,建立两个页面,分别为List.vue(首页)、Detail.vue(详情页)。

    然后在src目录下,建立一个router文件夹,文件夹中创建一个index.js前端路由文件

    前端路由文件index.js文件内容如下

    //路由页面
    
    import Vue from 'vue'
    
    //引入路由模块,看下终端,如果终端提示vue-router模块没有安装,安装即可
    import Router from 'vue-router'
    
    //分别引入List、Detail两个组件
    import List from '@/components/List'
    import Detail from '@/components/Detail'
    
    
    Vue.use(Router)
    
    //定义路由,这两个路由会被映射到App.vue的视口中
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'List',
          component: List
        },
        {
          path : '/league/:name',
          name : 'Detail',
          component : Detail
        },
      ]
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    第八步:处理跨域情况

    因为我们的express服务是在localhost:3000端口启动的,而我们的vue-cli创建的项目是在默认端口8080启动的,所以肯定会涉及到跨域的情况

    好在vue-cli为我们提供了解决跨域的配置入口

    找到根目录中config目录下面的index.js文件,里面有个配置项proxyTable,改写这个配置项如下即可

    在这里插入图片描述

    这时,当我们在前端用vue-resource访问 /api 的时候,就会被代理到 http://localhost:3000/api,从而获得需要的数据。说白了,也就是个转换工作。

    第九步:搭建页面

    到这里,所有准备工作已经完成,我们安心写前端代码即可。布局的话,就不多说了。交互方面主要就是在vue中的methods选项中定义一系列的方法,并且将方法通过**@click=“xxx”**方法绑定到对应的地方。

    项目写好后,就是打包了,并且将打包的dist文件夹作为express静态文件服务的目录。

    cnpm run build
    app.use(express.static('dist'))
    
    • 1
    • 2

    最后看下整个项目的目录结构

    ce访问 /api的时候,就会被代理到http://localhost:3000/api`,从而获得需要的数据。说白了,也就是个转换工作。

    第九步:搭建页面

    到这里,所有准备工作已经完成,我们安心写前端代码即可。布局的话,就不多说了。交互方面主要就是在vue中的methods选项中定义一系列的方法,并且将方法通过**@click=“xxx”**方法绑定到对应的地方。

    项目写好后,就是打包了,并且将打包的dist文件夹作为express静态文件服务的目录。

    cnpm run build
    app.use(express.static('dist'))
    
    • 1
    • 2

    最后看下整个项目的目录结构

    在这里插入图片描述

  • 相关阅读:
    线代小课整理
    cookie and session
    mysql DBA常用的sql
    常用的数值工具类
    【ES6】js 中class的extends、super关键字用法和避坑点
    SQL Server创建链接服务器的方法
    中关村e谷:产业服务终靠一颗赤诚之心
    Mysql中DML操作数据(增,删,改)
    Linux项目自动化构建工具-make/Makefile
    Golang入门(1)—— helloworld 初体验
  • 原文地址:https://blog.csdn.net/dfc_dfc/article/details/134365099