How to use mockjs to simulate data in vue project

brief introduction

If you don't talk much, bring me your hand. Cherish life and stay away from the backstage.

background

In the process of front-end and back-end separation mode project development, the front-end interface display and interaction logic often need the back-end interface data support, but the evil back-end can't keep up with the progress of our beautiful front-end sister.
So we can't help but sigh, isn't there a way to show the interface data perfectly without relying on the background, to ensure the integrity of front-end interaction without too much trouble? The answer is yes, of course. Let's invite our protagonist to the stage

Mockjs

introduce

The homepage of Mock official website is defined as: generate random data and intercept Ajax requests.

Portal & Example

Effect

  1. Reduce development costs

    In fact, the separation of front end and back end increases the development cost, but it can make us bear this cost in terms of the advantages it brings, but the goal of overcoming this cost has never stopped

  2. Coupling in front and back development

    After the detailed design of this stage is completed, the front end can start the development of this stage. Since the basic setting has been unified in the detailed design stage, the front end and back end should be completely independent in the development process. However, in the actual development, the front-end often leaves some interface receipt logic waiting to be filled after docking with the background, which can not completely complete the interface display and interaction logic of the front-end itself. The use of mockjs simulation interface and data front-end can completely separate the coupling cost between the development and the back-end to the greatest extent, and basically complete all front-end logic writing at the time of development

  3. Reduce the docking time of front and rear interfaces

    After the independent development of the front and back end, it enters the front and back end docking stage. Many project teams will spend a lot of debugging time and cost in this stage. However, in fact, if the front end completes the data and interaction logic, and the back end completes all the interface self tests, this stage should be very fast

  4. Front end self built project demonstration

    Many of the front-end open source projects have no background and simulate data demonstration. for example vue-element-admin,d2-admin,wl-admin.

Apply in project

  1. Introduce js dependency
    npm install mockjs      
    
  2. Create a mock folder to uniformly manage our mock data
  3. Try to create a demo.js in the mock folder
  4. Write the following code in mock/demo.js:
    import Mock from 'mockjs'
    

    Try to generate a random array of 20-40 pieces of data

    const projectList = Mock.mock({
        "list|20": [{
        'name': '@cname', // Chinese name
        'account': `@word`, // English words
        'phone': /1[3-9][0-9]{9}/, // Regular mode
        'deptName': Mock.mock('@cword(2,4)'), // Random 2-4 Chinese words
        'id': '@guid', // guid
       }]
     })
    
    There are several modes to choose from. See the official example for details.

    With the data, how can we return the data simulation through the interface

    export default [
        {
            url: '/Api/Project/GetList',
            type: 'post',
            response: (res) => {
                let _fileter_list = [];
                if(res.body.key){
                    let _fileter_list = projectList.fileter(i => i.name == res.body.key)
                }
    
                // Yes, you should have guessed that res.body is the data we passed into the interface. We can do some logical operations here
                // res contains the complete request header information
                return {
                    code: 200,
                    message: "Successful operation",
                    data: _fileter_list
                }     
                // Use return to return the data required by the front end
            }
        }
        ... // Multiple interfaces
    ]
    
  5. Now that the data is available, how can we make mockjs intercept the requests from our front end and distinguish the corresponding interfaces accurately?

    Create another index.js under the mock / folder to write our mock monitoring logic

    import Mock from 'mockjs' // Import mockjs
    
    import demoApi from './demo' // Import the js file of our simulation data
    
    const mocks = [
    {
        intercept: true, // You may need a switch to make the simulated request coexist with the real request
        fetchs: demoApi
    },
    
    // Copy a parse function to parse address bar parameters
    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, ' ') +
              '"}'
            ) 
        }
    
     // The key! Copy a front-end pattern building function (or you can build a 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))
              }
            }
          }
    }
    
    After the above one pass code, we have preliminarily completed the technical conditions of front-end analog data.
  6. But don't forget to introduce and use it in main.js
     import { mockXHR } from '../mock'
     if(process.env.NODE_ENV == 'development'){
        mockXHR();
     }
    
  7. Everything is ready, only owe request, you can write a request to try water now.
    axios.post('/Api/Project/GetList').then(res => {
        console.log(res)
    })
    
    However, we don't suggest you do it directly in the project!
  8. Bear it a little longer. Let's encapsulate the request a little.

    Create an api folder under src Then create a "request.js" under src/api /

    import Axios from "axios";
    
        // Define axios configuration 
        const http = Axios.create({
          baseURL: '', // Base URL of api
          withCredentials: true, // Enable cross domain identity certificate
          method: "post",
          headers: {
            "Content-Type": "application/json;charset=UTF-8"
          },
          timeout: 5000 // request timeout
        });
    
        // Set the global request times and the requested gap for automatic re request
        http.defaults.retry = 2;
        http.defaults.retryDelay = 1000;
    
        // request interceptor 
        http.interceptors.request.use(
          function (config) {
            return config;
          },
          function (error) {
            return Promise.reject(error);
          }
        );
    
        // Response interceptor
        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;
            // Collect error information
            switch (err_type) {
              case 400:
                err.message = "Invalid request";
                break;
    
              case 401:
                err.message = "The login has timed out due to no operation for a long time. Please login again";
                break;
    
              case 403:
                err.message = "access denied";
                break;
    
              case 404:
                err.message = `Error requesting address: ${errres.config.url}`;
                break;
    
              case 405:
                err.message = `Unauthorized`;
                break;
    
              case 408:
                err.message = "request timeout";
                break;
    
              case 500:
                err.message = "Server internal error";
                break;
    
              case 501:
                err.message = "Service not implemented";
                break;
    
              case 502:
                err.message = "Bad Gateway";
                break;
    
              case 503:
                err.message = "Service not available";
                break;
    
              case 504:
                err.message = "gateway timeout";
                break;
    
              case 505:
                err.message = "HTTP Version not supported";
                break;
    
              default:
                err.message = "Network fluctuation, please try again";
            }
    
            // 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;
    
  9. After encapsulating axios, unified management is still recommended for all api interfaces

    We build another project.js under the api / folder to manage all interfaces of the project modules

    import request from "../_request";
    
    // 1 get Department list interface
    function getProjectListApi(data) {
      return request({
        url: "/Api/Project/GetList",
        method: 'post',
        data
      });
    }
    
    // 2 add project interface
    function addProjectApi(data) {
      return request({
        url: "/Api/Project/Add",
        method: 'post',
        data
      });
    }
    
    // 3 delete project interface
    function delProjectApi(data) {
      return request({
        url: "/Api/Project/Add",
        method: 'post',
        data
      });
    }
    
    export {
      getProjectListApi, // 1 get Department list interface
      addProjectApi, // 2 add project interface
      delProjectApi, // 3 delete project interface
    }
    
  10. Next is the final step, which is used in the. vue file we developed ``` Import {getprojectlistapi} from "@ / API / project. JS"; / / import user list interface
export default {
    data(){
        return {
            projectList: []
        }
    },
    created(){
        this.getProjectList()
    },
    methods: {
      getProjectList(){
        getProjectListApi().then(res => {
            console.log(res)
        })
      }
    }
}
Concluding remarks
   Not surprisingly, after the above series of operations, our data has come out, and the application of mockjs in the project has been started. If you still want to be touched by me, come to my [Github](https://github.com/hql7) to make a friend~
   [GitHub] (https://github.com/hql7) & [segmentfault] (https://segmentfault.com/u/weilan deafa69d76) & [Nuggets] (https://juejin.im/user/591d141e0ce46300692184a4) & [CSDN] (https://blog.csdn.net/qq_) & [finch] (https://www.yuque.com/hooqilei)

Tags: Front-end mockjs axios github JSON

Posted on Thu, 05 Mar 2020 08:50:01 -0500 by sottwell