使用Mock,看这一篇就够了!!!

2,176 阅读3分钟

什么是Mock

image.png

  1. 前后端分离:让前端攻城师独立于后端进行开发。
  2. 开发无侵入:不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据。
  3. 数据类型丰富:支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等。
  4. 增加单元测试的真实性:通过随机数据,模拟各种场景。
  5. 用法简单:符合直觉的接口。
  6. 方便扩展:支持支持扩展更多数据类型,支持自定义函数和正则。

本地mock

安装

npm install mockjs

创建相关文件

  1. 在src/api/mockData/xxx.js中书写mock数据

image.png

export default {
  getHomeData:()=>{
    return {
      code:200,
      data: {
        tableData:[]
      }
    }
  }
}
  1. 在src/api/mock.js中书写mock配置

image.png

import Mock from 'mockjs'
import homeAPI from './mockData/home.js'

// 拦截请求
// 第一个参数是路径,第二个是返回的数据
Mock.mock('/home/getData',homeAPI.getHomeData)
  1. 引入mockjs

image.png

// 引入mock
import './api/mock.js'

在项目中使用

image.png

<script>
import {onMounted,ref} from 'vue'
import axios from 'axios'
export default {
  setup(){
    let tableData=ref([])
    const tableLabel={
      name: "课程",
      todayBuy: "今日购买",
      monthBuy: "本月购买",
      totalBuy: "总购买",
    }

    const getTableList= async()=>{
      // 直接在这个地方访问接口地址
      await axios.get('/home/getData').then(res=>{
        if(res.data.code){
          tableData.value=res.data.data.tableData
        }
      })
    }

    onMounted(()=>{
      getTableList()
    })
    return {tableData,tableLabel}
  }
}
</script>

线上mock

什么是fastmock

注册网站:129.204.116.48:3000/#/

本地mock是不可以部署服务器上的,线上 mock 将 mock 层独立出来,通过中间层的形式在前端和后端之前建立一道围栏,使用 fastmock 前端只需要修改自己的 XHR 请求的根地址(如配置 axios 的 axios.defaults.baseURL),后端只需要在开发前和前端约定好接口文档即可。等到后端开发完成 前端再将 XHR 请求地址替换回来进行联调开发调试即可。

fastmock的使用

image.png

image.png

{
      "code":200,
      "data": {
        tableData: [
          {
            name: "oppo",
            todayBuy: 500,
            monthBuy: 3500,
            totalBuy: 22000,
          },
          {
            name: "vivo",
            todayBuy: 300,
            monthBuy: 2200,
            totalBuy: 24000,
          },
          {
            name: "苹果",
            todayBuy: 800,
            monthBuy: 4500,
            totalBuy: 65000,
          },
          {
            name: "小米",
            todayBuy: 1200,
            monthBuy: 6500,
            totalBuy: 45000,
          },
          {
            name: "三星",
            todayBuy: 300,
            monthBuy: 2000,
            totalBuy: 34000,
          },
          {
            name: "魅族",
            todayBuy: 350,
            monthBuy: 3000,
            totalBuy: 22000,
          },
        ]
      }
    }

在项目里面调用

image.png

const getTableList= async()=>{
  await axios.get('https://www.fastmock.site/mock/83ac8f3bdb7bfc22fa577b26fa420c6f/api/home/
getTableData').then(res=>{
    if(res.data.code){
      tableData.value=res.data.data.tableData
    }
  })
}

大家可以看一下这个线上mock接口的地址: www.fastmock.site/mock/83ac8f…

image.png

配置一个项目级别的request.js

1.配置环境文件

一般在企业级项目里面有三个环境

  • 开发环境
  • 测试环境
  • 线上环境

在src/config/index.js

image.png

// 当前的环境
const env = import.meta.env.MODE || 'prod'

const EnvConfig = {
  development: {
    baseApi: '/api',
    mockApi: 'https://www.fastmock.site/mock/300283cb590d2022f75682f11a1848b0/api',
  },
  test: {
    baseApi: '//test.future.com/api',
    mockApi: 'https://www.fastmock.site/mock/300283cb590d2022f75682f11a1848b0/api',
  },
  prod: {
    baseApi: '//future.com/api',
    mockApi: 'https://www.fastmock.site/mock/300283cb590d2022f75682f11a1848b0/api',
  },
}

export default {
  env,
  // mock的总开关,
  mock: false,
  ...EnvConfig[env]
}

2.封装requset.js

在src/api/request.js

image.png

import axios from 'axios'
import config from '../config/index.js'
// 引入element组件的消息提示框
import { ElMessage } from 'element-plus'

const NETWORK_ERROR = '网络请求异常,请稍后重试'
// 封裝一個axios实例对象
const service = axios.create({
  baseURL: config.baseApi
})

// 请求之前
service.interceptors.request.use(req => {
  // 在这里定义header
  return req
})

// 在请求之后做一些事情
service.interceptors.response.use(res => {
  const { code, data, msg } = res.data
  if (code == 200) {
    return data
  } else {
    // 网络请求错误
    ElMessage.error(msg || NETWORK_ERROR)

    // 注意这里也要返回一个Promise
    return Promise.reject(msg || NETWORK_ERROR)
  }
})

// {
//   method:'get',
//   params:{

//   },
//   mock:false
// }

/**封装核心函数 */
function request(options) {
  options.method = options.method || 'get'

  // 让所有类型的axios请求携带的参数都放在data中
  // 当请求为get时,让data里的数据放在params中
  if (options.method.toLowerCase() == 'get') {
    options.params = options.data
  }

  // 对mock的处理
  let isMock = config.mock // 这一步是调用mock的总开关
  if (typeof options.mock !== 'undefined') {
    // 这一步是获取当axios请求的mock开关,优先级高于总开关
    isMock = options.mock
  }

  // 对线上环境做处理
  if (config.env == 'prod') {
    // 当是线上环境,要确保基地址一定不是mock
    service.defaults.baseURL = config.baseApi
  } else {
    // 当是其他环境
    service.defaults.baseURL = isMock ? config.mockApi : config.baseApi
  }

  return service(options)
}

export default request

3.封装api项目管理文件

image.png

/**
 * 项目API管理
 */

import request from './request.js'

// home组件 获取左侧表格的数据
export const getTableData = (params) => {
  return request({
    url: '/home/getTableData',
    mehtod: 'get',
    data: params,
    mock: true
  })
}

4.调用接口

image.png

import {getTableData} from '../../api/api.js'

export default {
    setup(){
        const getTableList= async()=>{
            let res=await getTableData()
            tableData.value=res
        }
        onMounted(()=>{
            getTableList()
        })
    }
}