Mockjs

Mockjs

介绍

Mock官网首页是这么定义的:生成随机数据,拦截 Ajax 请求。

demo

项目mock例子:https://gitee.com/huangchunhongzZ/vue-mock-test

1、在项目中应用

引入js依赖

npm install mockjs

建一个mock文件夹来统一管理我们的mock数据

在mock文件夹下建一个demo.js尝试一下
在mock/demo.js中写下如下代码:

import Mock from 'mockjs'
//随机生成一个20-40条的数组数据试试
const projectList = Mock.mock({
    "list|20": [{
    'name': '@cname', // 中文名
    'account': `@word`, // 英文单词
    'phone': /1[3-9][0-9]{9}/, // 正则模式
    'deptName': Mock.mock('@cword(2,4)'), // 随机2-4字中文单词
    'id': '@guid', // guid
   }]
 })
//有多种模式可选,具体见官方示例。

export default [
    {
        url: '/Api/Project/GetList',
        type: 'post',
        response: (res) => {
            
            // res.body就是我们传入到接口的数据,可以在这里做些逻辑操作
            // res包含完整的请求头信息
            return {
                code: 200,
                message: "操作成功",
                data:projectList 
            }     
            // 使用return返回前端需要的数据
        }
    }
     //... 多个接口
]

现在数据有了,我们如何让mockjs能够拦截到我们前端发出的请求,并能准确区分对应接口呢?

在mock/文件夹下再建一个index.js写我们mock的监听逻辑

import Mock from ‘mockjs’ // 导入mockjs


import demoApi from './demo' // 导入我们模拟数据的js文件

const mocks = [
{
    intercept: true, // 开关,模拟请求与真实请求并存
    fetchs: demoApi
},

// 解析地址栏参数解析函数
export function param2Obj(url) {
    const search = url.split('?')[1]
    if (!search) {
        return {}
    }
    return JSON.parse(
        '{"' +
            decodeURIComponent(search)
            .replace(/"/g, '\\"')
            .replace(/&/g, '","')
            .replace(/=/g, '":"')
            .replace(/\+/g, ' ') +
          '"}'
        ) 
    }
    
 // 前端模式构建函数(或者你也可以建一个mock server)
 export function mockXHR() {
      Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
      Mock.XHR.prototype.send = function() {
        if (this.custom.xhr) {
          this.custom.xhr.withCredentials = this.withCredentials || false

          if (this.responseType) {
            this.custom.xhr.responseType = this.responseType
          }
        }
        this.proxy_send(...arguments)
      }

      function XHR2ExpressReqWrap(respond) {
        return function(options) {
          let result = null
          if (respond instanceof Function) {
            const { body, type, url } = options
            // https://expressjs.com/en/4x/api.html#req
            result = respond({
              method: type,
              body: JSON.parse(body),
              query: param2Obj(url)
            })
          } else {
            result = respond
          }
          return Mock.mock(result)
        }
      }

      for (const i of mocks) {
        if(i.intercept){
          for(const fetch of i.fetchs){
            Mock.mock(new RegExp(fetch.url), fetch.type || 'get', XHR2ExpressReqWrap(fetch.response))
          }
        }
      }
}

经过上面一通代码之后,我们已经初步完成了前端模拟数据的技术条件。

但是你千万不要忘记了,在main.js引入并使用它哦

// mock
if (process.env.NODE_ENV === 'development') {
  const { mockXHR } = require('../mock')
  mockXHR()
}
// mock end

src下建一个api文件夹

然后再在src/api/下建一个_request.js

import Axios from "axios";

    // 定义axios配置 
    const http = Axios.create({
      baseURL: '', // api的base_url
      withCredentials: true, // 开启跨域身份凭证
      method: "post",
      headers: {
        "Content-Type": "application/json;charset=UTF-8"
      },
      timeout: 5000 // request timeout
    });

    // 设置全局的请求次数,请求的间隙,用于自动再次请求
    http.defaults.retry = 2;
    http.defaults.retryDelay = 1000;

    // 请求拦截器
    http.interceptors.request.use(
      function (config) {
        return config;
      },
      function (error) {
        return Promise.reject(error);
      }
    );

    // 响应拦截器
    http.interceptors.response.use(
      function (res) {
        return res;
      },
      function (err) {
        let config = err.config;
        let errres = err.response;
        let err_type = errres ? errres.status : 0;
        // 收集错误信息
        switch (err_type) {
          case 400:
            err.message = "请求无效";
            break;

          case 401:
            err.message = "由于长时间未操作,登录已超时,请重新登录";
            break;

          case 403:
            err.message = "拒绝访问";
            break;

          case 404:
            err.message = `请求地址出错: ${errres.config.url}`;
            break;

          case 405:
            err.message = `未授权`;
            break;

          case 408:
            err.message = "请求超时";
            break;

          case 500:
            err.message = "服务器内部错误";
            break;

          case 501:
            err.message = "服务未实现";
            break;

          case 502:
            err.message = "网关错误";
            break;

          case 503:
            err.message = "服务不可用";
            break;

          case 504:
            err.message = "网关超时";
            break;

          case 505:
            err.message = "HTTP版本不受支持";
            break;

          default:
            err.message = "网络波动,请重试";
        }

        // If config does not exist or the retry option is not set, reject
        if (!config || !config.retry) return Promise.reject(err);

        // Set the variable for keeping track of the retry count
        config.__retryCount = config.__retryCount || 0;

        // Check if we've maxed out the total number of retries
        if (config.__retryCount >= config.retry) {
          // Reject with the error
          return Promise.reject(err);
        }

        // Increase the retry count
        config.__retryCount += 1;

        // Create new promise to handle exponential backoff
        let backoff = new Promise(function (resolve) {
          setTimeout(function () {
            resolve();
          }, config.retryDelay || 1);
        });

        // Return the promise in which recalls axios to retry the request
        return backoff.then(function () {
          return http(config);
        });
      }
    );

    export default http;

封装了一下axios之后,所有的api接口仍建议统一管理

我们在api/文件夹下再建一个project.js用来统一管理项目模块的所有接口

import request from "../_request";

// 获取部门列表接口
function getProjectListApi(data) {
  return request({
    url: "/Api/Project/GetList",
    method: 'post',
    data
  });
}

export {
  getProjectListApi // 获取部门列表接口
}

接下来就是最后一步,在我们开发的.vue文件中使用啦

import { getProjectListApi } from "@/api/project.js"; // 导入用户列表接口

export default {
    data(){
        return {
            projectList: []
        }
    },
    created(){
        this.getProjectList()
    },
    methods: {
      getProjectList(){
        getProjectListApi().then(res => {
            console.log(res)
        })
      }
    }
}
上一篇:spring第三天之jdbcTemplate的crud操作


下一篇:mockjs使用指南