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.
Effect
- 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
- 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
- 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
- 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
- Introduce js dependency
npm install mockjs
- Create a mock folder to uniformly manage our mock data
- Try to create a demo.js in the mock folder
- Write the following code in mock/demo.js:
import Mock from 'mockjs'
Try to generate a random array of 20-40 pieces of data
There are several modes to choose from. See the official example for details.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 }] })
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 ]
- 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
After the above one pass code, we have preliminarily completed the technical conditions of front-end analog data.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)) } } } }
- But don't forget to introduce and use it in main.js
import { mockXHR } from '../mock' if(process.env.NODE_ENV == 'development'){ mockXHR(); }
- Everything is ready, only owe request, you can write a request to try water now.
However, we don't suggest you do it directly in the project!axios.post('/Api/Project/GetList').then(res => { console.log(res) })
- 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;
- 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 }
- 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)