首页 > 编程 > JavaScript > 正文

webpack4+express+mongodb+vue实现增删改查的示例

2019-11-19 12:33:14
字体:
来源:转载
供稿:网友

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

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 文件内部实现增删改查操作。

先在本地把数据库搭建起来后,再慢慢学习哦,我这边文章实现 vue+mongodb 实现增删改查也是基于上面这些文章的基础之上来进行的,特别是居于这篇 使用Mongoose类库实现简单的增删改查

( https://www.VeVB.COm/article/150381.htm) 来进行的,增删改查操作及使用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.VeVB.COm/article/150381.htm)如下代码:

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.VeVB.COm/article/150381.htm):

// 引入express 模块 const express = require('express');const router = express.Router();// 引入user.jsconst User = require('./user');// 新增一条数据 接口为addrouter.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代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表