【Vue+Mock】使用Mock模拟数据

前言

业务需求: 在前后端分离的开发模式中,需要前后端同时进入开发,但是在后端接口完成前,暂时没有可用的接口给前端使用的,如果先写静态页面后期再改的话,就会有重复工作。所以我们需要一种简单快速模拟数据的方式来协助开发。
实现思路: 接口文档的api及数据格式确认好之后,在前端采用Mock服务来模拟请求后台接口,按照接口文档的约定写入api、入参及出参等假数据,来模拟整个前后端联调的过程。


一、Mock简介

Mock.js官网提供的Mock示例Wiki文档,对Mock的使用描述的非常详细,并且可以在控制台快速试验这些方法。
在这里插入图片描述

二、Vue 项目中使用 mock.js 拦截数据

注:使用vue init project-name 创建的Vue项目

1、安装相关依赖

npm install axios –save
npm install mockjs --save-dev

2、模拟Mock数据

  1. 通过配置devServer.before选项,设置url访问路径及response响应数据,进行mock数据。
  2. 使用Mock.mock(),根据数据模板生成模拟数据。

2.1 Mock数据模拟方式一:devServer.before

  1. 在src文件夹下新建mock文件夹及index.js,在index.js中统一处理所有的mock数据
    在这里插入图片描述

  2. 在index.js文件中引入mock、声明随机数据、暴露拦截方法

const Mock = require('mockjs') // 引入mockjs

module.exports = function (app) { // 暴露一个函数,用于拦截请求时触发
  //监听http请求: app是一个请求实例,.get方法第一个参数传需要拦截的url,第二个参数传一个函数,该函数有两个参数(也可用app.post)
  app.get('/user/userInfo', (rep, res) => {
    // 设置要返回的数据(用mock随机生成的数据)
    let json = {
      id: '@id()', // 得到随机的id
      username: '@cname()', // 随机生成中文名字
      email: '@email()', // email
      ip: '@ip()', // ip地址
      description: '@paragraph()', // 描述
      date: '@date()' // 随机生成日期
    }
    // 通过res.json将上面声明的随机数据转为json并作为请求的返回值返回
    res.json(Mock.mock(json))
  })
}

  1. 配置config进行拦截

config.js(build->webpack.dev.conf.js或vue.config.js)中配置拦截,使用devServe.before钩子函数,用来监听来自web的http请求(在所有请求前先执行该函数)。引入刚刚编辑好的mock->index.js,该js文件暴露的函数将在这里调用。
(我这里是在build->webpack.dev.conf.js中配置的)

module.exports = {
    devServer: {
        before: require('./mock/index.js') // 引入 mock/index.js
    }
}

2.2 Mock数据模拟方法二:Mock.js

  1. 在src文件夹下新建mock文件夹及index.js,在index.js中统一处理所有的mock数据
  2. 在index.js文件中引入mock、声明随机数据、暴露拦截方法
import Mock from 'mockjs'

//表示需要拦截的 URL,可以是 URL 字符串或 URL 正则。
//表示需要拦截的 Ajax 请求类型。例如 GET、POST、PUT、DELETE 等。
//表示数据模板,可以是对象或字符串。例如 { 'data|1-10':[{}] }、'@EMAIL'。
Mock.mock('/user/userInfo', 'get', {
  id: '@id()', // 得到随机的id
  username: '@cname()', // 随机生成中文名字
  email: '@email()', // email
  ip: '@ip()', // ip地址
  description: '@paragraph()', // 描述
  date: '@date()' // 随机生成日期
})
  1. 在main.js中引入require("./mock/index.js")

3、在vue使用

发送http请求的URL与mock中定义的URL需一致

import axios from "axios";
export default {
  mounted() {
    axios.get('/user/userInfo').then(res => {
      console.log(res);
    }).catch(err => {
      console.log(err);
    })
  }
}

4、效果

在这里插入图片描述

PS:如果发送http请求的URL与mock中定义的URL不匹配或不存在的话,就会报404错误! 请确认URL没问题。

三、Mock使用优化

1、mock数据使用单独的js文件

1.1 场景描述

所有接口的mock数据都在index.js里处理,在接口太多的情况下查找及修改很不方便,因此将模拟的mock数据单独放入对应的js文件(可按接口或业务需求进行处理)。

1.2 解决方案

  1. 在mock文件夹下新建userInfo.js,在userInfo.js写入该接口模拟的mock数据。
/**
 * 写法一
 */
// module.exports = {
//   id: '@id()', // 得到随机的id
//   username: '@cname()', // 随机生成中文名字
//   email: '@email()', // email
//   ip: '@ip()', // ip地址
//   description: '@cparagraph()', // 描述
//   date: '@date()' // 随机生成日期
// }

/**
 * 写法二
 */
// const json = {
//   id: '@id()', // 得到随机的id
//   username: '@cname()', // 随机生成中文名字
//   email: '@email()', // email
//   ip: '@ip()', // ip地址
//   description: '@cparagraph()', // 描述
//   date: '@date()' // 随机生成日期
// }
// module.exports = json

/**
 * 写法三
 */
const userInfo = () => {
  const json = {
    id: '@id()', // 得到随机的id
    username: '@cname()', // 随机生成中文名字
    email: '@email()', // email
    ip: '@ip()', // ip地址
    description: '@cparagraph()', // 描述
    date: '@date()' // 随机生成日期
  }
  return { data: { result: json, code: 200, message: 'success' } }
}
module.exports = {
  getUserInfo: userInfo
}
  1. 修改mock->index.js文件,使用require('./userInfo.js')来获取模拟的json数据
const Mock = require('mockjs') // 引入mockjs

module.exports = function (app) { // 暴露一个函数,用于拦截请求时触发
  //监听http请求: app是一个请求实例,.get方法第一个参数传需要拦截的url,第二个参数传一个函数,该函数有两个参数(也可用app.post)
  app.get('/user/userInfo', (rep, res) => {
    // 设置要返回的数据(用mock随机生成的数据)
    // let json = {
    //   id: '@id()', // 得到随机的id
    //   username: '@cname()', // 随机生成中文名字
    //   email: '@email()', // email
    //   ip: '@ip()', // ip地址
    //   description: '@cparagraph()', // 描述
    //   date: '@date()' // 随机生成日期
    // }
    // const json = require('./userInfo.js')  // userInfo.js直接返回json数据(对应写法一、二)
    const json = require('./userInfo.js').getUserInfo() // userInfo.js返回函数(对应写法三)
    // 通过res.json将上面声明的随机数据转为json并作为请求的返回值返回
    res.json(Mock.mock(json))
  })
}

2、mock获取get、post请求参数

2.1 场景描述

在前后端分离的开发模式下,想要尽可能的模拟真实情况,如不同的请求方式get/post,接口超时响应等。

2.2 解决方案

2.2.1 设置延时请求到数据

1.不设置延时很有可能遇到坑【敲黑板】,因为真实的请求是需要时间的,mock不设置延时是拿到数据马上返回。
2.要模拟Loading加载效果时。

//设置延迟响应,模拟向后端请求数据
Mock.setup({
    timeout: 800
})

2.2.2 get请求参数

Mock.mock("/api/order/index", "get", (options) =>{
  let result = {} // 数据或对象
  return { data: { result: result, code: 200, message: 'success' } }
});

注意:get 请求如果带参数的话,是在URL后面加上参数,因此和设置的URL没有匹配上,会导致URL没找到请求失败。
举个例子:使用 Mock.mock(“/user/getUserInfo”, “get”, mockData) 时,它只会拦截URL等于/user/getUserInfo的请求,而对于带参数的请求,如/user/getUserInfo?id=123就拦截不到。

建议将URL改写成正则表达式的URL
Mock.mock(RegExp(url + ".*"), "get", mockData);

Mock.mock(RegExp("/api/order/index"+ ".*");, "get", (options) =>{
  let result = {} // 数据或对象
  return { data: { result: result, code: 200, message: 'success' } }
});

2.2.3 post请求参数

post请求可以是 URL 字符串或 URL 正则。

Mock.mock("/api/order/index", "post", (options) =>{
  let result = {} // 数据或对象
  return { data: { result: result, code: 200, message: 'success' } }
});

3、mock返回列表及分页数据

3.1 场景描述

在mock文件夹下新建order.js,以订单列表为例,我们模拟了订单列表数据,但列表数据还需分页才能满足业务需求。

3.2 解决方案

在现有的列表数据基础上进行改造,增加分页功能。

  1. 未分页的orderLIst
const orderList = () => {
  const dataList = []
  for (let i = 0; i < 100; i++) {
    const newObject = {
      orderId: '@id()', // 得到随机的id
      orderType: '@cword("全次极加延", 1)', // 得到随机的文本
      createTime: '@datetime()' // 随机生成日期
    }
    dataList.push(newObject)
  }
  return { data: { result: dataList, code: 200, message: 'success' }}
}
module.exports = {
  getOrderList: orderList
}
  1. 分页的orderLIst
const orderList = (params) => {
  const dataList = []
  for (let i = 0; i < 100; i++) {
    const newObject = {
      orderId: '@id()', // 得到随机的id
      orderType: '@cword("全次极加延", 1)', // 得到随机的文本
      createTime: '@datetime()' // 随机生成日期
    }
    dataList.push(newObject)
  }
  const { page, pageSize } = params
  const total = dataList.length
  const len = total / pageSize
  const totalPage = Number.isInteger(len) ? len + 1 : len
  const list = dataList.slice((page - 1) * pageSize, page * pageSize)
  return {
    data: {
      result: {
        page,
        pageSize,
        total,
        totalPage,
        list
      }, code: 200, message: 'success'
    }
  }
}
module.exports = {
  getOrderList: orderList
}

4、控制mock在开发环境使用,在生产环境禁用

4.1 场景描述

mock拦截所有的axios请求,根据请求做出相应的响应。在前后端分离开发时我们使用mock获得相应的数据,但当和后端联调时不禁用mock的话,就无法获得后端接口数据,因此我们来配置一个mock模拟数据的开关。

4.2 解决方案

  1. 在vue中通过设置main.js中的Vue.config.productionTip来决定模式。默认为false是生产环境。
  2. 我们在config/dev.env.js和config/prod.env.js中设置变量。
// dev.env.js下的配置。
module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',
  MOCK: true //开发环境使用mock
})

// prod.env.js下的配置
module.exports = {
  NODE_ENV: '"production"',
  MOCK: false // 生产环境禁用mock
}

  1. 在main.js中设置process.env.MOCK && require("./mock/index.js")

process.env.MOCK这句就是判断刚才设置的值,如果是true,才会执行语句引入mock,如果是false,则后面的语句不执行,即不引入mock。


总结

Mock原理:前端发送请求后,在devServe.before中运行mock/index.js暴露的函数,捕捉到url一致的请求,直接返回mock设定的数据,有返回值就不会继续真实的请求,拦截成功之后,请求没有往后台去,而是在前端完成了虚拟请求。

### 如何在Vue2项目中使用Mock.js模拟数据 #### 安装依赖包 为了能够在Vue2项目中使用`mock.js`进行数据模拟,需要先安装相应的依赖包。这可以通过命令行工具npm完成。 ```bash npm install mockjs --save-dev npm install axios --save ``` 上述命令会将`mock.js`作为开发依赖项加入到项目之中,并且也引入了用于发起HTTP请求的`axios`库[^4]。 #### 创建并配置Mock服务 接下来,在项目的源码根目录下创建一个新的文件夹命名为`mock`,并在其中建立一个名为`index.js`的JavaScript文件用来编写具体的模拟逻辑: // src/mock/index.js ```javascript import Mock from 'mockjs' const data = Mock.mock({ 'list|1-10': [{ 'id|+1': 1, 'name': '@cname' }] }) Mock.mock('/api/list', 'get', () => { return data.list; }) ``` 这段代码利用`Mock.mock()`函数定义了一组模拟返回的数据结构以及对应的API路径和请求方式。这里设置的是当接收到针对`/api/list`地址发出GET类型的网络请求时,则按照预设模式生成相应数量的对象列表作为回应内容[^1]。 #### 导入Mock模块至Vue实例 为了让整个应用程序能够识别这些自定义好的假数据接口,在入口文件main.js里添加如下几行语句即可实现自动加载功能: ```javascript // main.js import '@/mock' // 加载mock数据 ``` 通过这种方式便可以在不改变原有业务逻辑的前提下轻松切换真实环境下的服务器端交互行为与本地调试期间所使用的伪造版本之间的转换操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值