手把手教你使用mock

145 阅读2分钟

安装

npm i  mockjs -S

设置文件目录

/**
 * @author halley
 * 目录结构 - 注意新建文件夹于根目录与src平级
 * ├─mock
 * |  |_index.js        // mock 根目录入口文件
 * |  |_mock-server.js  // mockServer 基础服务封装
 * |  |_sign.js...      // mock数据设置
 * ├─src
 * │  |_App.vue  
 * |  |_main.js
 * ├─vue.config.js
 */
 

mock相关文件配置

mock-server.js
const chokidar = require('chokidar')
const path = require('path')
const chalk = require('chalk')
const mockDir = path.join(process.cwd(), 'mock')
const configFile = path.join(process.cwd(), 'src/api/config.js')
function deleteCache() {
  Object.keys(require.cache).forEach((i) => {
    if (i.includes(mockDir) || i.includes(configFile)) {
      delete require.cache[require.resolve(i)]
    }
  })
}
function registerApi(app) {
  let mockLastIndex
  const { mocks } = require('./index.js')
  mocks.forEach((api) => {
    const { url, method = 'post', statusCode, responseCode, response } = api
    app[method](`/mock-api${url}`, (req, res) => {
      if (statusCode && statusCode !== 200) {
        // res.status(statusCode).send(statusCode);
        res.sendStatus(statusCode)
      } else {
        res.status(200).send(
          response instanceof Function
            ? response(req, res)
            : {
              code: responseCode || 200,
              data: response,
              msg: responseCode === 200 || !responseCode ? 'success' : 'fail',
              success: responseCode === 200 || !responseCode ? true : false,
            },
        )
      }
    })
    mockLastIndex = app._router.stack.length
  })
  const mockRoutesLength = Object.keys(mocks).length
  return {
    mockRoutesLength: mockRoutesLength,
    mockStartIndex: mockLastIndex - mockRoutesLength,
  }
}
module.exports = (app, server, compiler) => {
  const mockRoutes = registerApi(app)
  var mockRoutesLength = mockRoutes.mockRoutesLength
  var mockStartIndex = mockRoutes.mockStartIndex

  // 默认修改文件不会更新, 使用chokidar进行监听
  chokidar
    .watch([mockDir, configFile], {
      ignored: /mock-server/,
    })
    .on('all', (event, path) => {
      console.log(event)
      try {
        // remove mock routes stack
        app._router.stack.splice(mockStartIndex, mockRoutesLength)
        // clear routes cache
        deleteCache()

        const mockRoutes = registerApi(app)
        mockRoutesLength = mockRoutes.mockRoutesLength
        mockStartIndex = mockRoutes.mockStartIndex
        // console.log(" Mock Server hot reload success! ");
        console.log(
          chalk.magentaBright(
            `\n > Mock Server hot reload success! changed  ${path}`,
          ),
        )
      } catch (error) {
        // console.log(error);
        console.log(chalk.redBright(error))
      }

      // console.log(require.cache)
    })
}

sign.js
const Mock = require('mockjs')
const testMockApi1 = '/testMockApi1'  //注意要与@api里接口定义统一;当然也可以将接口路径统一定义到confg中引入
const testMockApi2 = '/testMockApi2'
module.exports = [
  {
    url: testMockApi1,
    // disabled:true,
    // method: "get",
    // statusCode:500,
    response: Mock.mock({
      'items|10': [
        {
          archiveStatus: '@integer(0, 1)',
          billId: '@id',
          billNo: '@id',
          billType: '@integer(0, 2)',
          createByAd: '@name',
          createByName: '@cname',
          createTime: '@datetime',
          deleteFlag: '@integer(0, 1)',
          doucumentNo: '@id',
          editTime: '@datetime',
          fileName: '@string',
          fileType: '@integer(0, 3)',
          fileTypeDesc: '@string',
          id: '@id',
          recoveryFileResp: [
            {
              contractId: 0,
              createByAd: '@name',
              createByName: '@cname',
              createTime: '@datetime',
              deleteFlag: 0,
              draftFlag: 0,
              editTime: '@datetime',
              fileFormat: '',
              fileId: 0,
              fileMdfive: '',
              fileName: '',
              fileSizeDesc: '',
              fileType: 0,
              fileTypeDesc: '',
              id: '@id',
              remark: '@string',
              seqId: '@id',
              size: 0,
              url: '@url',
            },
          ],
          recoveryNo: '@id',
          recoveryStatus: 0,
          recoveryStatusDesc: '@string',
          recoveryType: 0,
          recoveryTypeDesc: '@string',
          remark: '@string',
          sealBpmTaskId: 0,
          sealFlag: 0,
          sealNo: '@string',
          seqId: 0,
          status: 0,
          statusDesc: '@string',
        },
      ],
    }).items,
  },
  {
    url: testMockApi2,
    response: {
      fileType: [
        {
          code: 1,
          desc: '合同',
        },
        {
          code: 2,
          desc: '补充协议',
        },
        {
          code: 3,
          desc: '其他',
        },
      ],

      recoveryType: [
        {
          code: 1,
          desc: '标准合同',
        },
        {
          code: 2,
          desc: '非标合同',
        },
      ],
    },
  },
]
index.js
const sign = require('./sign') // 可扩展多个自定义文件
const mocks = [...sign]
module.exports = {
  disabled: false, // 是否关闭全部mock接口
  mocks,
}
vue.config.js
devServer: {
     before: require('./mock/mock-server.js'),
     ......
}
request.js
首先引入mock :
    const mockApis = require('../../mock')
在request拦截器中设置开发环境mock重定向:
    service.interceptors.request.use(config => {
        ......
        // 此处用于本地mock服务
        if (process.env.NODE_ENV === 'development') {
          if (mockApis.disabled === false && mockApis.mocks && mockApis.mocks.length) {
              mockApis.mocks.forEach((item) => {
                 if (!item.disabled && item.url.indexOf(config.url) > -1) {
                     config.baseURL = `mock-api`
                 }
              })
           }
        }
        ......
    })

配置完成后使用测试

src\api\testApi.js 接口api定义
import request from '@/utils/request'

// 测试mock是否可用eg:1
export function testMockApi1(query) {
  return request({
    url: '/testMockApi1',
    method: 'post',
    params: query
  })
}

// 测试mock是否可用eg:2
export function testMockApi2(query) {
  return request({
    url: '/testMockApi2',
    method: 'post',
    params: query
  })
}
views\index.vue视图界面操作获取mock数据
<template>
    <el-button @click="getData">mock获取数据</el-button>
</template>

<script>
    import { testMockApi1, testMockApi2 } from "@/api/testApi";
    methods: {
        testMockApi1().then(res=>{
            console.log(res,'===testMockApi1')
        })
    }
</script>
以上就是全部配置内容,此种方式配置优点
  • 无需安装插件即可在浏览器network网络请求中看到请求
  • 由于request中进行baseURL复写,开发环境网络请求容易与后端请求进行区分
  • mock index文件可以通过设置disabled进行一键关闭(当然后续可以根据各个环境key进行设置mock开关)