Vue使用mockjs模拟数据请求接口

707 阅读3分钟

原文链接:blog.csdn.net/qq_53729147…

MockJs

一、为什么使用mockjs

在做开发时,当后端的接口还未完成,前端为了不影响工作效率,手动模拟后端接口。

1.我们可以使用json文件来模拟后台数据,但比较局限,无法模拟数据的增删改查

2.使用json-server模拟,但不能随机生成所需数据

3.使用mockjs模拟后端接口,可随机生成所需数据,可模拟对数据的增删改查

二、mock优点

1.前后端分离

2.可随机生成大量的数据

3.用法简单

4.数据类型丰富

5.可扩展数据类型

6.在已有接口文档的情况下,我们可以直接按照接口文档来开发,将相应的字段写好,在接口完成 之后,只需要改变url地址即可。

官网地址:mockjs.com/

github地址:github.com/nuysoft/Moc…

三、mockjs语法及使用

1、使用mockjs 项目安装mockjs

安装

npm install mockjs

项目中新建mock文件

//引入mock模块

import Mock from 'mockjs'

将mock文件在main.js中导入

import Vue from 'vue'
import App FROM './App.vue'
import './mock/index.js'
 
 Vue.config.productionTip = false
 
 new Vue({
   render:h => h(App),
 }).$mount('#app')

3、mock拦截请求

定义get请求

Mock.mock('api/get/news','get',()=>{
     return{
         status:200,
         message:"获取数据成功"
     }
 })

定义post请求

Mock.mock('api/post/news','post',()=>{
     return{
         status:200,
         message:"获取数据成功"
     }
 })

4、实现新闻管理案例

获取数据 接口地址::/api/get/news

接口参数:

pageindex:页码 pagesize:每页的条数 请求类型:get

返回的数据:

{
     status:200,
         message:"获取新闻列表成功",
         list:[
         {
             "id":1,
             "title":"解忧杂货店",
             "content":"《解忧杂货店》是日本作家东野圭吾写作的长篇小说。2011年《小说野性时代》连载,于2012年3月由角川书店发行单行本",
             "img_url":"http://t15.baidu.com/it/u=2090705107,20534764&fm=224&app=112&f=JPEG?w=500&h=500&s=61D0718656561FFFE504A51703000067",
             "add_time":"1984-04-03 11:43:37"}
         ],
         total:50
     }
 }

添加新闻

接口地址::/api/add/news

接口参数:

title:'标题' content:内容 请求类型:post

返回的数据:

{
     status:200,
         message:"获取新闻列表成功",
         list:[
         {
             "id":1,
             "title":"解忧杂货店",
             "content":"《解忧杂货店》是日本作家东野圭吾写作的长篇小说。2011年《小说野性时代》连载,于2012年3月由角川书店发行单行本",
             "img_url":"http://t15.baidu.com/it/u=2090705107,20534764&fm=224&app=112&f=JPEG?w=500&h=500&s=61D0718656561FFFE504A51703000067",
             "add_time":"1984-04-03 11:43:37"}
         ],
         total:50
     }
 }

删除新闻

接口地址::/api/delete/news

接口参数:

id;新闻id 请求类型:post

返回的数据:

{
     status:200,
         message:"获取新闻列表成功",
         list:[
         {
             "id":1,
             "title":"解忧杂货店",
             "content":"《解忧杂货店》是日本作家东野圭吾写作的长篇小说。2011年《小说野性时代》连载,于2012年3月由角川书店发行单行本",
             "img_url":"http://t15.baidu.com/it/u=2090705107,20534764&fm=224&app=112&f=JPEG?w=500&h=500&s=61D0718656561FFFE504A51703000067",
             "add_time":"1984-04-03 11:43:37"}
         ],
         total:50
     }
 }

接口名称相同,现在只是mockjs拦截了请求,只要上线的时候把mock注释,调用服务器接口,测试一下即可。防止后端返回数据不完善或者字段有遗漏

完整案例

mock/index.js

// 引入mockjs
 import Mock from "mockjs";
 ​
 const { newsList } = Mock.mock({
     "newsList|75": [{
         id: "@increment",
         title: "@ctitle()",
         content: "@cparagraph(5,10)",
         img_url: "@image('50*50','#FF83FA','#FCFCFC','png','mono')",
         add_time: "@date(yyyy-MM-dd hh:mm:ss)",
     }, ],
 });
 ​
 console.log(newsList);
 var getQuery = (url, name) => {
     console.log(url, name);
     const index = url.indexOf("?");
     if (index !== -1) {
         const queryStrArr = url.substr(index + 1).split("&");
         for (var i = 0; i < queryStrArr.length; i++) {
             const itemArr = queryStrArr[i].split("=");
             console.log(itemArr);
             if (itemArr[0] === name) {
                 return itemArr[1];
             }
         }
     }
     return null;
 };
 ​
 // 定义获取新闻列表的数据
 // /api/get/news?pageinde1&pagesize=10
 Mock.mock(/\/api\/get\/news/, "get", (options) => {
     // 获取传递参数pageindex,pagesize
     const pageindex = getQuery(options.url, "pageindex");
     const pagesize = getQuery(options.url, "pagesize");
     console.log(pageindex);
     console.log(pagesize);
     const start = (pageindex - 1) * pagesize;
     const end = pagesize * pageindex;
     const totalPage = Math.ceil(newsList.length / pagesize);
 ​
     //  pageindex:1 pagesize:10 返回0-9条数据  2-10-(10-19) 3-10(20-29)
     // 数据的起始位置:(pageindex-1)*pagesize 结束位置:pageindex*pagesize
     const list = pageindex > totalPage ? [] : newsList.slice(start, end);
     return {
         status: 200,
         message: "获取新闻列表成功",
         list: list,
         total: totalPage,
     };
 });
 ​
 // 定义添加新闻的数据
 Mock.mock("/api/add/news", "post", (options) => {
     const body = JSON.parse(options.body);
     console.log(body);
     newsList.push(
         Mock.mock({
             id: "@increment",
             title: body.title,
             content: body.content,
             img_url: "@image('50*50','#FF83FA','#FCFCFC','png','mono')",
             add_time: "@date(yyyy-MM-dd hh:mm:ss)",
         })
     );
     return {
         status: 200,
         message: "添加成功",
         list: newsList,
         total: newsList.length,
     };
 });
 ​
 // 定义删除新闻
 Mock.mock("/api/delete/news", "post", (options) => {
     console.log(options);
     const body = JSON.parse(options.body);
     console.log(body);
     const index = newsList.findIndex((item) => {
         return item.id === body.id;
     });
     newsList.splice(index, 1);
     console.log(index);
     return {
         status: 200,
         message: "添加成功",
         list: newsList,
         total: newsList.length,
     };
 });
 console.log(Mock);
App.vue

<template>
   <div>
     <!-- 搜索 -->
     <div class="add">
       <input type="text" v-model="title" placeholder="输入标题" />
       <input type="text" v-model="content" placeholder="输入内容" />
       <button @click="add">添加</button>
     </div>
     <!--  表格-->
     <div class="news_list">
       <table>
         <tr>
           <th>图片</th>
           <th>标题</th>
           <th>内容</th>
           <th>时间</th>
           <th>操作</th>
         </tr>
         <tr v-for="item in list" :key="item.id">
           <td><img :src="item.img_url" alt="" /></td>
           <td>{{ item.title }}</td>
           <td>{{ item.content }}</td>
           <td>{{ item.add_time }}</td>
           <td><button class="remove" @click="remove(item.id)">删除</button></td>
         </tr>
       </table>
     </div><!-- 上下页 -->
     <div class="pages">
       <button @click="prevPage">上一页</button>
       <button @click="nextPage">下一页</button>
     </div>
   </div>
 </template><script>
   import axios from 'axios'
   export default {
     data() {
       return {
         title: '',
         content: '',
         list: [],
         pageindex: 1,
         title: '',
         content: ''
       }
     },
     methods: {
       add() {
         axios
           .post('/api/add/news', {
             title: this.title,
             content: this.content
           })
           .then((res) => {
             console.log(res)
           })
       },
       //获取新闻列表数据
       getNewsList() {
         axios
           .get('/api/get/news', {
             params: {
               pageindex: this.pageindex,
               pagesize: 10
             }
           })
           .then((res) => {
             console.log(res)
             this.list = res.data.list
           })
       },
       nextPage() {
         this.pageindex++
         this.getNewsList()
       },
       prevPage() {
         this.pageindex--
         this.getNewsList()
       },
       // 删除新闻
       remove(id) {
         // console.log(id);
         axios
           .post('/api/delete/news', {
             id
           })
           .then((res) => {
             console.log(res)
           })
       }
     },
     created() {
       this.getNewsList()
     },
     mounted() {}
   }
 </script><style>
   .add input {
     border-radius: 5px;
     border: none;
     outline: none;
     border: 1px solid #999;
     padding: 5px;
     margin-right: 5px;
   }
   button {
     width: 100px;
     height: 30px;
     background: #409eff;
     color: none;
     outline: none;
     border-radius: 5px;
     margin-left: 5px;
     cursor: pointer;
     border: 0;
     color: #fff;
   }
   .news_list {
     width: 1220px;
     height: 495px;
     overflow-y: scroll;
     overflow-x: hidden;
     margin: 10px;
   }
   table {
     border-collapse: collapse;
     height: 495px;
     overflow-y: scroll;
     overflow-x: hidden;
     margin: 10px;
     border: 1px solid rgb(94, 92, 92);
   }
   table th {
     font-size: 16px;
     height: 30px;
     width: 224px;
     font-weight: normal;
     border: 1px solid rgb(94, 92, 92);
   }
   table td {
     font-size: 12px;
     padding: 5px;
     border: 1px solid rgb(94, 92, 92);
   }
   table td:nth-child(4) {
     width: 150px;
   }
   table td:nth-child(2) {
     min-width: 100px;
   }
   table img {
     width: 80px;
     height: 80px;
   }
   table .remove {
     background: #f56c6c;
   }
 </style>