Mockjs如何方便的在基于`webpack`构建的项目中使用

axios和mock

为什么把axiosmock放在一起呢?

因为在开发环境它们有时候需要配合使用,现代项目往往是前后端分离式的开发,前端和后端的主要联系在于接口的联调,前端往往需要依赖后端提供的接口返回的数据来编码页面逻辑。但因为分离式的开发,前端可能在需要某个接口的时候,这个接口后端还没有开发完成,无法调用。mock便是为了应付这种场景,后端没数据没有关系,我前端自己造,后端提供接口文档说明接口规范,前端根据文档正常定义xmlhttp请求,然后调用mock拦截请求,返回mock定义的数据,这样就实现了伪后端联调的效果。

那么,这个过程如何实现呢?

不着急,我们先分别看看这两个插件的用法。

axios

官方文档见这里

axios是一款基于Promise的用于浏览器node.js环境的http请求插件。

现以常见的基于npmwebpack项目为例,来大概介绍下其使用方法:

  1. 首先安装axios插件,我这里用的yarn,用npm或者cnpm之类的请自行切换对应的命名。
    yarn add axios
    
  2. 统一请求配置和设置拦截器

    assets/js/目录下新建http.js文件,添加公共的请求配置和对应的requestresponse拦截器。
    import axios from 'axios'
    
    const instance = axios.create({
      timeout: 30000,
      headers: {}
    });
    
    // 添加请求拦截器
    instance.interceptors.request.use(function (config) {
      // 在发送请求之前做些什么,比如说这里统一调用loading遮罩层,给每个请求添加时间戳的参数
      return config;
    }, function (error) {
      // 对请求错误做些什么
      return Promise.reject(error);
    });
    
    // 添加响应拦截器
    instance.interceptors.response.use(function (response) {
      // 对响应数据做点什么,比如说移除遮罩层,根据后端返回code判断是不是登录失效而统一配置跳到登录页
      if(response.status === 200) return response.data;
      return Promise.reject(response);
    }, function (error) {
      // 对响应错误做点什么
      return Promise.reject(error);
    });
    
    export default instance;
    
  3. 使用

    main.js或者vue项目的store.js中引入http.js中实例化的axios对象instance
    import $http from '../http.js'
    
    main.js中,可以将$http挂载到Vue原型上,这样就可以直接在各组件中调用。
    // 挂载到原型上后可通过this.$http来调用
    Vue.prototype.$http = $http
    
    又或者直接在store.js(可以根据实际使用自由拆分再合并到store.js)中引入,然后配置请求,在各组件中用dispatch的方法调用。
    import Vue from 'vue'
    import Vuex from 'vuex'
    import http from '../http.js'
    Vue.use(Vuex)
    export default new Vuex.Store({
      state: {},
      mutations: {},
      actions: {
        getWeatherInfo({commit},str){ // 获取城市天气,str为城市code,如深圳为101280601
          return new Promise((resolve, reject) => {
            http({
              method: 'get',
              url: `/api/weather/city/${str}`, // 该请求的ip为http://t.weather.sojson.com,有兴趣的可以试试,能够调通
            }).then(rs => {
              if(rs.result === 'success') {
                resolve(rs)
              }else{
                reject(rs)
              }
            })
          })
        },
      },
      modules: {}
    })
    
    经过上面这样的配置后,你可以在组件中这样调用:
    this.$store.dispatch('getWeatherInfo',101280601).then(rs => {/* ... */})
    
    上面这种配置方式的好处是service层和views层的代码可以很好的解耦,后期某个接口若有改动,直接去store.js修改相应请求的配置,而不用一个一个去搜索使用到了这个接口的每处代码然后一一修改。

mock

官方文档见这里

先搬个官网的使用说明:

# 安装
yarn add mockjs
// 使用 Mock
var Mock = require('mockjs')
var data = Mock.mock({
    // 属性 list 的值是一个数组,其中含有 1 到 10 个元素
    'list|1-10': [{
        // 属性 id 是一个自增数,起始值为 1,每次增 1
        'id|+1': 1
    }]
})
// 输出结果
console.log(JSON.stringify(data, null, 4))

说实话,上面的代码是看懂了,但并没有什么用,因为光靠这个使用方法,我也不知道如何将它和axios的请求联系起来。网上搜索许久,也不知道个个都是大神还是怎么回事,几乎都是复制粘贴的内容,而内容主体与官网说明没有多少出入,看完依旧很懵。

那么到底该怎么使用呢?浪里淘沙般的操作还是让我找到了一些有帮助的帖子,按照思路整了一番,终于找到一种能让自己满意使用mock.js的模式了。

组合使用

我对mockjs的期望一直是非侵入式拦截,并且有个类似总开关的存在可以决定是否开启mockjs

那如何来使用mockjs呢?

  1. 首先在某文件夹中新建mock.js文件,其内容大致如下:
    const MOCK = require('mockjs')
    MOCK.mock('/api/weather/city/101280601','get',{
      status: 'error',
      msg: '天气查询失败'
    })
    
  2. main.jsrequire加载mock.js文件
    if(process.env.NODE_ENV === 'development'){ // 区分环境,这样即使打包时忘了把下面代码注释掉也不会影响生产环境
      require('../mock') // 不需要开启mock
    }
    
    这样你在某组件中调用这个天气查询接口,你console.log返回的内容会发现返回的是你自己定义的mock数据,查看控制台的network也会发现这个请求并没有被发送出去。但这个过程给人的体验与正常从后端接口获取数据无异。

    所以这是什么情况呢?

    原来,只要你的项目中有做require('mockjs')这个动作,那么mockjs便会拦截所有请求,不管你是否配置了某个接口应该返回什么样的假数据。这个你可以从network中验证这一点。

    那么,在实际开发过程中,为了正常使用mockjs,我们在配置接口的时候都要做两份,一份是假设可以正常从后端获取数据的逻辑代码,一份是mock定义的模拟数据代码。

    mockjs使用的基本方式如下:,
    MOCK.mock(url,method,mockData) // api,方式,假数据
    
    关于axiosmockjs一些细节方面的东西都可以参考官方文档。

你可能感兴趣的:(Mockjs如何方便的在基于`webpack`构建的项目中使用)