在讲解之前,我们先来看看效果如下所示:

1)整个页面的效果如下:

2) 新增数据效果如下:

3) 新增成功如下:

4) 编辑数据效果如下:

5) 编辑成功效果如下:

6) 删除数据效果如下:

7) 删除成功效果如下:

8) 查询效果如下:

如上的效果,下面我们还是和之前一样,先看看我们整个项目的架构如下所示:

### 目录结构如下:
demo1 # 工程名
| |--- dist # 打包后生成的目录文件
| |--- node_modules # 所有的依赖包
| |----database # 数据库相关的文件目录
| | |---db.js # mongoose类库的数据库连接操作
| | |---user.js # Schema 创建模型
| | |---addAndDelete.js # 增删改查操作
| |--- app
| | |---index
| | | |-- views # 存放所有vue页面文件
| | | | |-- list.vue # 列表数据
| | | | |-- index.vue
| | | |-- components # 存放vue公用的组件
| | | |-- js # 存放js文件的
| | | |-- css # 存放css文件
| | | |-- store # store仓库
| | | | |--- actions.js
| | | | |--- mutations.js
| | | | |--- state.js
| | | | |--- mutations-types.js
| | | | |--- index.js
| | | | |
| | | |-- app.js # vue入口配置文件
| | | |-- router.js # 路由配置文件
| |--- views
| | |-- index.html # html文件
| |--- webpack.config.js # webpack配置文件
| |--- .gitignore
| |--- README.md
| |--- package.json
| |--- .babelrc # babel转码文件
| |--- app.js # express入口文件

如上目录架构是我现在整个项目的架构图,其中database目录下存放 db.js ,该文件最主要是使用 mongoose 数据库连接操作,user.js 文件是创建一个Schema模型,也可以理解为表结构,addAndDelete.js 文件内部实现增删改查操作。

如果对mongodb数据库相关的知识点不是很熟悉的话,可以先看下我之前写的一些关于mongodb文章(https://www.cnblogs.com/tugenhua0707/category/1240772.html), 先在本地把数据库搭建起来后,再慢慢学习哦,我这边文章实现 vue+mongodb 实现增删改查也是基于上面这些文章的基础之上来进行的,特别是居于这篇 使用Mongoose类库实现简单的增删改查
(https://www.cnblogs.com/tugenhua0707/p/9256605.html) 来进行的,增删改查操作及使用Schema 创建模型 都是居于这篇文章的基础之上再进行使用vue来重构下的。本篇文章也是依赖于饿了么vue组件进行开发的。

先来分别讲下代码结构吧:

1)使用express创建服务器

首先我们在项目的根目录新建app.js, 该app.js 主要实现的功能是 启动 3001端口的服务器,并且使用 bodyParser进行解析数据,如下代码:

// 引入express模块
const express = require('express'); // 创建app对象
const app = express(); const addAndDelete = require('./database/addAndDelete'); const bodyParser = require("body-parser") app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); // 使用
app.use('/api', addAndDelete); // 定义服务器启动端口
app.listen(3001, () => {
console.log('app listening on port 3001');
});

进入我们项目的根目录后,运行 node app.js 即可创建一个 http://127.0.0.1:3001 的服务器页面了。

2)数据库连接
在database/db.js 链接 mongodb://localhost:27017/dataDb 数据库。使用mongoose类库,如果不理解mongoose类库的话,可以返回来看我这篇文章(https://www.cnblogs.com/tugenhua0707/p/9256605.html)如下代码:

var mongoose = require('mongoose');
var DB_URL = 'mongodb://localhost:27017/dataDb'; /* 链接 */
mongoose.connect(DB_URL); /* 链接成功 */
mongoose.connection.on('connected', function() {
console.log('Mongoose connection open to ' + DB_URL);
}); // 链接异常
mongoose.connection.on('error', function(err) {
console.log('Mongoose connection error:' + err);
}); // 链接断开 mongoose.connection.on('disconnected', function() {
console.log('Mongoose connection disconnected');
});
module.exports = mongoose;

3)创建数据模型
在database/user.js 中使用 Schema创建一个模型,也就是说上面的 dataDb是数据库名称,这边使用schema创建的模型就是表结构的字段,有如下 name, age, sex 三个字段,代码如下所示:

/*
定义一个user的Schema
*/
const mongoose = require('./db.js');
const Schema = mongoose.Schema; // 创建一个模型
const UserSchema = new Schema({
name: { type: String }, // 属性name,类型为String
age: { type: Number, default: 30 }, // 属性age,类型为Number,默认值为30
sex: { type: String }
}); // 导出model模块
const User = module.exports = mongoose.model('User', UserSchema);

4)实现增删改查路由接口

如下所有的增删改查的代码如下(如果代码看不懂的话,还是返回看这篇文章即可:https://www.cnblogs.com/tugenhua0707/p/9256605.html):

// 引入express 模块
const express = require('express'); const router = express.Router(); // 引入user.js
const User = require('./user'); // 新增一条数据 接口为add
router.post('/add', (req, res) => {
const user = new User({
name: req.body.name,
age: req.body.age,
sex: req.body.sex
});
user.save((err, docs) => {
if (err) {
res.send({ 'code': 1, 'errorMsg': '新增失败' });
} else {
res.send({ "code": 0, 'message': '新增成功' });
}
});
}); // 查询数据
router.post('/query', (req, res) => {
const name = req.body.name,
age = req.body.age,
sex = req.body.sex;
const obj = {};
if (name !== '') {
obj['name'] = name;
}
if (age !== '') {
obj['age'] = age;
}
if (sex !== '') {
obj['sex'] = sex;
}
User.find(obj, (err, docs) => {
if (err) {
res.send({ 'code': 1, 'errorMsg': '查询失败' });
} else {
res.send(docs);
}
});
}); // 根据 _id 删除数据
router.post('/del', (req, res) => {
const id = req.body.id;
// 根据自动分配的 _id 进行删除
const whereid = { '_id': id };
User.remove(whereid, (err, docs) => {
if (err) {
res.send({ 'code': 1, 'errorMsg': '删除失败' });
} else {
res.send(docs);
}
})
}); // 更新数据
router.post('/update', (req, res) => {
console.log(req.body)
// 需要更新的数据
const id = req.body.id,
name = req.body.name,
age = req.body.age,
sex = req.body.sex;
const updateStr = {
name: name,
age: age,
sex: sex
};
const ids = {
_id: id
};
console.log(ids);
User.findByIdAndUpdate(ids, updateStr, (err, docs) => {
if (err) {
res.send({ 'code': 1, 'errorMsg': '更新失败' });
} else {
res.send(docs);
}
});
});
module.exports = router;

5)搭建vue页面,如何通过页面的接口请求?

在app/index/views/list.vue 基本代码如下(所有的html代码是基于饿了么vue组件的,最主要一些form表单组件的用法及表格的插件及弹窗的插件),代码如下:

<style lang="stylus">
#list-container
width 100%
</style>
<template>
<div id="list-container" style="margin:20px auto">
<div style="width:100%;overflow:hidden;">
<el-form ref="form" label-width="80px">
<div style="float:left;width:20%">
<el-form-item label="姓名">
<el-input v-model="name"></el-input>
</el-form-item>
</div>
<div style="float:left;width:20%">
<el-form-item label="年龄">
<el-input v-model="age"></el-input>
</el-form-item>
</div>
<div style="float:left;width:20%">
<el-form-item label="性别">
<el-select v-model="sex">
<el-option
v-for="item in options2"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</div>
<el-button type="primary" style="margin-left:20px;" @click="query(true)">查 询</el-button>
<el-button type="success" @click="newAdd">新 增</el-button>
</el-form>
</div>
<div style="width:90%; margin: 0 auto; border: 1px solid #ebebeb; border-radius: 3px;overflow:hidden;">
<el-table
:data="tableData"
style="width: 100%">
<el-table-column
prop="name"
label="姓名"
width="180">
</el-table-column>
<el-table-column
prop="age"
label="年龄"
width="180">
</el-table-column>
<el-table-column
prop="sex"
label="性别">
</el-table-column>
<el-table-column
fixed="right"
label="操作"
width="100">
<template slot-scope="scope">
<el-button type="text" size="small" @click="editFunc(scope.row)">编辑</el-button>
<el-button type="text" size="small" @click="delFunc(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<el-dialog
title="新增"
:visible.sync="dialogVisible"
width="30%">
<el-form label-width="40px">
<div style="float:left;width:100%">
<el-form-item label="姓名">
<el-input v-model="add.name"></el-input>
</el-form-item>
</div>
<div style="float:left;width:100%">
<el-form-item label="年龄">
<el-input v-model="add.age"></el-input>
</el-form-item>
</div>
<div style="float:left;width:100%">
<el-form-item label="性别">
<el-select v-model="add.sex">
<el-option
v-for="item in options2"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</div>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="addConfirm">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="编辑"
:visible.sync="dialogVisible2"
width="30%">
<el-form label-width="40px">
<div style="float:left;width:100%">
<el-form-item label="姓名">
<el-input v-model="update.name"></el-input>
</el-form-item>
</div>
<div style="float:left;width:100%">
<el-form-item label="年龄">
<el-input v-model="update.age"></el-input>
</el-form-item>
</div>
<div style="float:left;width:100%">
<el-form-item label="性别">
<el-select v-model="update.sex">
<el-option
v-for="item in options2"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</div>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="editConfirm">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="提示"
:visible.sync="dialogVisible3"
width="30%">
<div>是否确认删除?</div>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible3 = false">取 消</el-button>
<el-button type="primary" @click="delConfirm">确 定</el-button>
</span>
</el-dialog>
</div>
</template> <script type="text/javascript">
export default {
data() {
return {
formLabelWidth: '120px',
name: '',
age: '',
sex: '',
options2: [
{
value: '1',
label: '男'
}, {
value: '2',
label: '女'
}
],
tableData: [],
// 新增页面
add: {
name: '',
age: '',
sex: ''
},
// 修改页面
update: {
name: '',
age: '',
sex: ''
},
dialogVisible: false,
dialogVisible2: false,
dialogVisible3: false,
row: null,
_id: ''
}
},
created() {
this.query();
},
methods: {
setData(datas) {
if (datas.length > 0) {
for (let i = 0; i < datas.length; i++) {
if (datas[i].sex * 1 === 1) {
this.$set(datas[i], 'sex', '男');
} else if (datas[i].sex * 1 === 2) {
this.$set(datas[i], 'sex', '女');
}
}
}
return datas;
},
// 查询数据
query(isquery) {
const obj = {
name: this.name,
age: this.age,
sex: this.sex
};
this.$http.post('/api/query', obj).then((res) => {
if (res.ok) {
this.tableData = res.body ? this.setData(res.body) : [];
if (isquery) {
this.$message({
message: '查询成功',
type: 'success'
});
}
} else {
if (isquery) {
this.$message({
message: '查询失败',
type: 'warning'
});
}
this.tableData = [];
}
});
},
newAdd() {
this.dialogVisible = true;
},
editFunc(row) {
this.dialogVisible2 = true;
this._id = row._id;
this.$set(this.$data.update, 'name', row.name);
this.$set(this.$data.update, 'age', row.age);
this.$set(this.$data.update, 'sex', row.sex);
this.row = row;
},
delFunc(row) {
this.dialogVisible3 = true;
console.log(row);
this.row = row;
},
// 编辑页面提交
editConfirm() {
const id = this._id,
name = this.update.name,
age = this.update.age,
sex = this.update.sex;
const obj = {
id: id,
name: name,
age: age,
sex: sex
};
this.$http.post('/api/update', obj).then((res) => {
if (res.ok) {
// 删除成功
this.$message({
message: '更新成功',
type: 'success'
});
// 重新请求下查询
this.query(false);
} else {
// 删除成功
this.$message({
message: '更新失败',
type: 'success'
});
}
this.dialogVisible2 = false;
});
},
// 删除提交
delConfirm() {
const obj = {
'id': this.row._id
};
this.$http.post('/api/del', obj).then((res) => {
console.log(res.body)
if (res.body.ok) {
// 删除成功
this.$message({
message: '删除成功',
type: 'success'
});
// 成功后,触发重新查询下数据
this.query();
} else {
// 删除失败
this.$message({
message: res.body.errorMsg,
type: 'warning'
});
}
this.dialogVisible3 = false;
});
},
// 新增提交
addConfirm() {
// 新增的时候,姓名,年龄,性别 不能为空,这里就不判断了。。。
const obj = {
name: this.add.name,
age: this.add.age,
sex: this.add.sex
};
this.$http.post('/api/add', obj).then((res) => {
console.log(111);
console.log(res);
if (res.body.code === 0) {
this.$message({
message: '新增成功',
type: 'success'
});
// 成功后,触发重新查询下数据
this.query();
} else {
this.$message({
message: res.body.errorMsg,
type: 'warning'
});
}
this.dialogVisible = false;
});
}
}
}
</script>

6. 解决跨域问题,及接口如何访问的?

首先我们是使用express启动的是 http://127.0.0.1:3001 服务器的,但是在我们的webpack中使用的是8081端口的,也就是说页面访问的是http://127.0.0.1:8081/ 这样访问的话,因此肯定会存在接口跨域问题的,因此我们需要在webpack中使用 devServer.proxy 配置项配置一下,如下代码配置:

module.exports = {
devServer: {
port: 8081,
// host: '0.0.0.0',
headers: {
'X-foo': '112233'
},
inline: true,
overlay: true,
stats: 'errors-only',
proxy: {
'/api': {
target: 'http://127.0.0.1:3001',
changeOrigin: true // 是否跨域
}
}
},
}

因为我list.vue页面所有的请求都是类似于这样请求的 this.$http.post('/api/query', obj); 因此当我使用 /api/query请求的话,它会被代理到 http://127.0.0.1:3001/api/query, 这样就可以解决跨域的问题了,同时我们在项目的根目录中的 将路由应用到 app.js 中,有如下这句代码:

const addAndDelete = require('./database/addAndDelete');
app.use('/api', addAndDelete);

当请求http://127.0.0.1:3001/api/query的时候,会自动使用 addAndDelete.js 中的 /query的接口方法。

查看github代码

webpack4+express+mongodb+vue 实现增删改查的更多相关文章

  1. 利用koa实现mongodb数据库的增删改查

    概述 使用koa免不了要操纵数据库,现阶段流行的数据库是mongoDB,所以我研究了一下koa里面mongoDB数据库的增删改查,记录下来,供以后开发时参考,相信对其他人也有用. 源代码请看:我的gi ...

  2. vue的增删改查

    我们把这些用户信息保存到list的数组中,然后增删改查就在这个数组上进行: list: [ { username: 'aaaaa', email: '123@qq.com', sex: '男', pr ...

  3. 关于vue的增删改查操作

    利用vue也可以实现数据的增删改查,只是未涉及到数据库,只是在浏览器页面中进行操作. 将datas数组中的数据循环输出: 再增加一行,用于保存新数据,编辑数据后保存: 此时,数据已经呈现出来,开始进行 ...

  4. MongoDB --- 02. 基本操作,增删改查,数据类型,比较符,高级用法,pymongo

    一.基本操作 . mongod 启动服务端 2. mongo 启动客户端 3. show databses 查看本地磁盘的数据库 4. use 库名 切换到要使用的数据库 5. db 查看当前使用的数 ...

  5. nodejs对mongodb数据库的增删改查操作(转载)

    首先要确保mongodb的正确安装,安装参照:http://docs.mongodb.org/manual/tutorial/install-mongodb-on-debian-or-ubuntu-l ...

  6. 69.nodejs对mongodb数据库的增删改查操作

    转自:https://www.cnblogs.com/sexintercourse/p/6485381.html 首先要确保mongodb的正确安装,安装参照:http://docs.mongodb. ...

  7. MongoDB学习之--增删改查(1)

    本文是对mongodb学习的一点笔记,主要介绍最简单的增删改操作,初学,看着API,有什么错误,希望大家指正:(使用官方驱动) 1.增 增加操作是最简单的,构造bsonDcument插入即可: 方式1 ...

  8. MongoDB学习之--增删改查(2)

    昨天简单介绍了官方驱动操作MongoDB进行增删查操作的,今天继续介绍更新操作..... 方法简介 官方驱动中更新操作使用collection的Update方法,有泛型和非泛型两个版本: 其签名如下( ...

  9. 使用node和express+mongodb实现数据增删改功能

    2018即将过去,2019即将来临,前端技术不断在在更新,学的东西越来越多.我们只有不断的学习,才不能被淘汰.在前后端分离的一个时代,后端提供接口,前端调用接口,逻辑判断,每个都是独立的工作.如果自己 ...

随机推荐

  1. Newtonsoft.Json(Json.net)的基本用法

    Newtonsoft.Json(Json.net)的基本用法 其它资料 JSON详解 添加引用: 使用NuGet,命令:install-package Newtonsoft.Json 实体类: pub ...

  2. 包含Blob字段的表无法Export/Import

    最近一直用MySQL-Front的导出导出工具完成数据库的备份,确实比较方便快捷. 后来增加了一张表,其中有blob字段,上传几个文件后,发现导出不好用了,进度条长期处于停滞状态. 想想也是,要把bl ...

  3. 关于MYSQL group by 分组按时间取最大值的实现方法!

    类如 有一个帖子的回复表,posts( id , tid , subject , message , dateline ) , id 为 自动增长字段, tid为该回复的主题帖子的id(外键关联), ...

  4. mysql创建自定义函数与存储过程

    mysql创建自定义函数与存储过程 一 创建自定义函数 在使用mysql的过程中,mysql自带的函数可能不能完成我们的业务需求,这时就需要自定义函数,例如笔者在开发过程中遇到下面这个问题 mysql ...

  5. UESTC_Rain in ACStar 2015 UESTC Training for Data Structures&lt;Problem L&gt;

    L - Rain in ACStar Time Limit: 9000/3000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Other ...

  6. atoi atol strtod strtol strtoul _gcvt

    如果以下函数,您在使用的时候,总是输出一个莫名的值,是因为您忘记了引用头文件 #include <stdlib.h> 1- atoi int atoi(const char *nptr); ...

  7. 第八届河南省赛C.最少换乘(最短路建图)

    C.最少换乘 Time Limit: 2 Sec  Memory Limit: 128 MB Submit: 94  Solved: 25 [Submit][Status][Web Board] De ...

  8. 最短路径算法专题2----Dijkstra

    这个算法适用于求单源最短路径,从一点出发,到其余个点的最短路径. 算法要点: 1.用二维数组存放点到点的距离-----不能相互到达的点用MAX代替距离 2.用dis数组存放源点到任意其他一点的距离-- ...

  9. iOS进阶之页面性能优化

    转载:http://www.jianshu.com/p/1b5cbf155b31 前言 在软件开发领域里经常能听到这样一句话,"过早的优化是万恶之源",不要过早优化或者过度优化.我 ...

  10. Java经验杂谈(2.对Java多态的理解)

    多态是面向对象的重要特性之一,我试着用最简单的方式解释Java多态: 要正确理解多态,我们需要明确如下概念:・定义类型和实际类型・重载和重写・编译和运行 其中实际类型为new关键字后面的类型. 重载发 ...