Vue+Ant Design Vue+Mockjs----mock篇

Mock

mock 介紹

mockjs官方使用文檔

目的

方便生成隨機數據,攔截Ajax請求。

  偶爾會寫一些前端的項目,參考一些比較知名的UI框架,裏面很多例子都會把數據直接寫在裏面,作爲參考,因此很多項目裏面也會這樣手寫數據,直接寫死在前端,將代碼與mock數據緊密結合在一起,每次需要修改數據,都需要直接改動到代碼層,前端本身改動就非常大,如此頻繁的修改代碼層面顯然不是很好的實踐。

同時手寫的數據,美觀與真實性差異就看作者水平了。

優點
  • 非常簡單強大,入手快
  • 攔截api請求,mock出真實的前後端交互情況
  • 更改mock數據方便,與業務代碼分離,頻繁修改也不會有太大的危險
  • 在後端接口準備好前,通過mock接口來模擬與後臺的交互,同時調整數據結構。
  • 開發過程中,mock數據也可以與後端提前討論,引導後臺的數據結構更加合理。
  • 後臺開發完以後,可以一次性切換接口
缺點
  • 靈活性不夠,無法mock後臺一些異常處理返回
  • Build成靜態文件以後線上無法使用(或許我沒有找對方法)
comment

   針對第一個問題,忽然想到一種方案,或許你可以在同一個接口裏面,mock不同的response,然後採用隨機函數,隨機的返回各種異常response,這樣可以測試前端應對各種後臺error作出的處理是否符合預期。

安裝

cd myProject

#僅安裝到本地開發環境
npm install mockjs --save-dev  

mock 實現

src
│       
└───api  //api文件夾,所有的接口都到單獨抽出來,放在該目錄下
│       index.js  //入口函數,對外暴露
│       search.js  //爲每一類接口單獨創建的文件,一類接口統一放在一個目錄下
│
└───mock
        index.js   //所有的mock  api都會寫在下面,如果需要,也可以拆分

mock/index.js

/**
 * data mock refer to http://mockjs.com
 *
 */
const Mock = require('mockjs');
const util = require('./util');

module.exports = function (app) {

  app.get('/mock/v1/search', function (rep, res) {
     let result = {
      "data|24": [{
        "date": "@date('yyyy-MM-dd')",
        "logNum": "@natural(60, 1000)"
      }
      ]
    };
    //util.wrapResultSuccess  包裝了response返回,規範統一
    res.send(util.wrapResultSuccess(Mock.mock(result).data));
  });


}

vue.config.js

//vue cli3 配置文件
  devServer: {
    port: port,
    open: true,
    host: '127.0.0.1',
    https: false,
    hotOnly: false,
    overlay: {
      warnings: false,
      errors: true
    },
  #根據當前環境,把整個mock目錄加載到項目中,每次修改mock文件需要重啓
    before: process.env.ENV == 'mock' ? require('./src/mock'):null,
  },

api/index.js

/**
 * api interface
 */

import search from '@/api/search'

export default {
  search
}

api/search.js

/**
 * article模塊接口列表
 */

import axios from '@/plugins/request';
import trend from "@/plugins/handle"


const search = {

  statusPing () {
    return axios.get(`/status_ping`);
  },

  //search
  search (body) {
    return axios.get(`v1/search`, body);
  },


export default search;


utils/request.js

把axiso做了一層封裝,每一次前端請求都會把x-request-id帶給後臺,後臺打印日誌的時候,都會打印這個id,方便日後追蹤問題,同事針對一些後臺的error,可以做一些統一的處理。


import router from '@/pages/login/router';

const xss = require("xss");

let instance = axios.create({
  timeout: 1000 * 60
    });

instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

function getRandomTraceId() {
  let characters = 'abcdefghijklmnopqrstuvwxyz1234567890';
  let result = '';
  let idLength = 32;

  try {
    for (let index = 0; index < idLength; index++) {
      result += characters[parseInt(Math.random() * characters.length, 10)];
    }
  } catch (error) {
    result = 'getRandomTraceIdError';
  }

  return result;
}
/**
 * request interceptor
 * Before each request, if token exists, carry it in the request header
 */
instance.interceptors.request.use(
    config => {
      // console.log(JSON.stringify(config));

      //add trace id for request
      config.headers['x-request-id'] = getRandomTraceId();

      //xss filter request url
      config.url = xss(config.url);


      // 登錄流程控制中,根據本地是否存在token判斷用戶的登錄情況
      // 但是即使token存在,也有可能token是過期的,所以在每次的請求頭中攜帶token
      // 後臺根據攜帶的token判斷用戶的登錄情況,並返回給我們對應的狀態碼
      // 而後我們可以在響應攔截器中,根據狀態碼進行一些統一的操作。
      // const token = store.state.token;
      // token && (config.headers.Authorization = token);
      return config;
    },
    error => Promise.error(error))


instance.interceptors.response.use(

    res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res),

    error => {
      const {response} = error;
      if (response) {
        errorHandle(response.status, response.data.message);
        return Promise.reject(response);
      } else {
        // 處理斷網的情況
        // eg:請求超時或斷網時,更新state的network狀態
        // network狀態在app.vue中控制着一個全局的斷網提示組件的顯示隱藏
        // 關於斷網組件中的刷新重新獲取數據,會在斷網組件中說明
        if (!window.navigator.onLine) {
          // store.commit('changeNetwork', false);
        } else {
          return Promise.reject(error);
        }
      }
    });

export default instance;

main.js

直接把api類掛載到vue上,這樣方便使用,也可以直接到使用類裏面去引入

import api from '@/api'

Vue.prototype.$api = api;

window.APP=new Vue({
  router,
  i18n,
  api,
  store,
  render: h => h(App)
}).$mount('#app')

how to use

async getData(){
     let response = await this.$api.search.search(request);
       if (response.status == 200 && response.data.data) {
       console.log(`response.data.data = &{response.data.data}`);
       }
}
發佈了65 篇原創文章 · 獲贊 132 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章