1. 新建一个dva项目。使用antd 或者antd-mobile组件库。
$ npm install dva-cli -g $ dva -v $ dva new dva-quickstart $ npm start
$ npm install antd babel-plugin-import --save 或者是 $ npm install antd-mobile babel-plugin-import --save
导入方式css
{ "entry": "src/index.js", "env": { "development": { "extraBabelPlugins": [ "dva-hmr", "transform-runtime", ["import", { "libraryName": "antd-mobile", "style": "css" }] ] }, "production": { "extraBabelPlugins": [ "transform-runtime", ["import", { "libraryName": "antd-mobile", "style": "css" }] ] } } }
2. 在该项目的src中utils 创建名为request文件夹。
$ cd dva-quickstart $ cd src $ cd utils
新建文件夹名为request,然后在request文件夹下面创建名为helpers的文件夹以及index.js 和 README.md , request.js 如图所示:
在helpers 下建三个js文件 combineURL.js , isAbsoluteURL.js , serialize.js
image.png
combineURL.js中 :
// Creates a new URL by combining the specified URLs
const combineURL = (baseUrl, path) => {
return `${baseUrl.replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`;
};
export default combineURL;
combineURL.js中 :
// Creates a new URL by combining the specified URLsconst combineURL = (baseUrl, path) => { return `${baseUrl.replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`; };export default combineURL;
isAbsoluteURL.js中 :
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed// by any combination of letters, digits, plus, period, or hyphen.// https://www.ietf.org/rfc/rfc3986.txtconst isAbsoluteURL = (url) => /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);export default isAbsoluteURL;
serialize.js中 :
import { isPresent } from 'lib/lang';const encode = (value) => { return encodeURIComponent(value) .replace(/%40/gi, '@') .replace(/%3A/gi, ':') .replace(/%24/g, '$') .replace(/%2C/gi, ',') .replace(/%20/g, '+') .replace(/%5B/gi, '[') .replace(/%5D/gi, ']'); };// Encode a set of form elements as a string for submission.const serialize = (params) => { const ret = []; Object.keys(params).forEach(key => { const value = params[key]; if (isPresent(value)) { ret.push(`${encode(key)}=${encode(value)}`); } }); return ret.join('&'); };export default serialize;
3. 在utils下创建一个与request同级的lang.js
lang.js 如下:
export const isPresent = (obj) => { return typeof obj !== 'undefined' && obj !== null; };export const isBlank = (obj) => { return typeof obj === 'undefined' || obj === null; };export const isBoolean = (obj) => { return typeof obj === 'boolean'; };export const isNumber = (obj) => { return typeof obj === 'number'; };export const isString = (obj) => { return typeof obj === 'string'; };export const isArray = (obj) => { return Array.isArray(obj) || Object.prototype.toString.call(obj) === '[object Array]'; };export const isDate = (obj) => { return obj instanceof Date && !isNaN(obj.valueOf()); };export const isFunction = (obj) => { return typeof obj === 'function'; };export const isJsObject = (obj) => { return obj !== null && (isFunction(obj) || typeof obj === 'object'); };export const isPromise = (obj) => { return isPresent(obj) && isFunction(obj.then); };export const isEmpty = (obj) => { if (isBlank(obj)) { return true; } if (obj.length === 0) { return true; } for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { return false; } } return true; };export const normalizeBlank = (obj) => { return isBlank(obj) ? null : obj; };export const normalizeBool = (obj) => { return isBlank(obj) ? false : obj; };export const stringify = (token) => { if (isString(token)) { return token; } if (isBlank(token)) { return String(token); } const ret = token.toString(); const newLineIndex = ret.indexOf('\n'); return (newLineIndex === -1) ? ret : ret.substring(0, newLineIndex); };export class PromiseWrapper { // Excutes promises one by one, e.g. // const promise = () => new Promise(...) // const promise2 = () => new Promise(...) // sequentialize([ promise, promise2 ]) static sequentialize = promiseFactories => { let chain = Promise.resolve(); promiseFactories.forEach(factory => { chain = chain.then(factory); }); return chain; } // Promise finally util similar to Q.finally // e.g. finally(promise.then(...)) /* eslint-disable consistent-return */ static finally = (promise, cb) => promise.then(res => { const otherPromise = cb(); if (typeof otherPromise.then === 'function') { return otherPromise.then(() => res); } }, reason => { const otherPromise = cb(); if (typeof otherPromise.then === 'function') { return otherPromise.then(() => { throw reason; }); } throw reason; }) }/* eslint-enable consistent-return */export class StringWrapper { static equals = (s1, s2) => s1 === s2; static contains = (s, substr) => s.indexOf(substr) !== -1; static compare = (a, b) => { if (a < b) { return -1; } else if (a > b) { return 1; } return 0; } }/* eslint-disable max-params */export class DateWrapper { static create( year, month = 1, day = 1, hour = 0, minutes = 0, seconds = 0, milliseconds = 0 ) { return new Date(year, month - 1, day, hour, minutes, seconds, milliseconds); } static fromISOString(str) { return new Date(str); } static fromMillis(ms) { return new Date(ms); } static toMillis(date) { return date.getTime(); } static now() { return Date.now() || new Date(); } static toJson(date) { return date.toJSON(); } }/* eslint-enable max-params */
这个是dva自动生成的request.js 把这个文件换下名字requests.js,它与lang.js同级。
4. 打开在request文件下request.js,进行编辑:
request.js
import fetch from 'dva/fetch';import { isEmpty } from '../lang';import serialize from './helpers/serialize';import combineURL from './helpers/combineURL';import isAbsoluteURL from './helpers/isAbsoluteURL';import { apiBaseUrl } from '../../config';import { Toast } from 'antd-mobile';const wait = ms => new Promise(resolve => setTimeout(resolve, ms));const timeout = (p, ms = 30 * 1000) => Promise.race([ p, wait(ms).then(() => { const error = new Error(`Connection timed out after ${ms} ms`); error.statusCode = 408; throw error; }), ]);// Request factoryfunction request(url, options, method) { const { endpoint, ...rest } = interceptRequest(url, options, method); const xhr = fetch(endpoint, rest).then(interceptResponse); return timeout(xhr, request.defaults.timeout).catch((error) => { // return Promise.reject(error); }); } request.defaults = { baseURL: apiBaseUrl, timeout: 10 * 5000, headers: { Accept: 'application/json', }, };// Headers factoryconst createHeaders = () => { const headers = { ...request.defaults.headers, }; // const auth = JSON.parse(localStorage.getItem('auth'+sessionStorage.getItem("hid"))); // const token = sessionStorage.getItem('token'); // <Michael> 登录location获取到的token存放l // if (auth) { // // Toast.info(`请稍等: ${token}`, 2); // // Toast.loading(''); // headers.Authorization = auth.Token; // } else if (token) { // // <Michael>; // // Toast.info(`请稍等: ${token}`, 2); // // Toast.loading(''); // headers.Authorization = token; // } headers.Authorization = "app"; return headers; };// Request interceptorfunction interceptRequest(url, options, method) { let endpoint; if (isAbsoluteURL(url)) { endpoint = url; } else { endpoint = combineURL(request.defaults.baseURL, url); } let data = { method, endpoint, headers: createHeaders(), }; if (!isEmpty(options)) { data = { ...data, ...options, }; if (options.json) { data.headers['Content-Type'] = 'application/json;charset=utf-8'; data.body = JSON.stringify(options.json); } if (options.form) { data.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'; data.body = serialize(options.form); } if (options.body) { data.body = options.body; const auth = JSON.parse(localStorage.getItem('auth'+sessionStorage.getItem("hid"))); if (auth) { if (auth && options.body instanceof FormData && !options.body.hasPatientid) { // options.body.append('patientid', auth.Patientid); } } } if (options.params) { endpoint += `?${serialize(options.params)}`; data.endpoint = endpoint; } } return data; }// Response interceptor/* eslint-disable consistent-return */function interceptResponse(response) { return new Promise((resolve, reject) => { const emptyCodes = [204, 205]; // Don't attempt to parse 204 & 205 if (emptyCodes.indexOf(response.status) !== -1) { return resolve(response.ok); } if (response.ok) { const contentType = response.headers.get('Content-Type'); if (contentType.includes('application/json')) { resolve(response.json()); } resolve(response); } if (response.status === 401) { // return Toast.fail('认证信息已过期,请重新登录', 2, () => { // return Toast.fail('请重新登录', 2, () => { localStorage.removeItem('auth'+sessionStorage.getItem("hid")); // sessionStorage.removeItem('token'); location.reload(); // TODO:跳转登录路由 // }); } const error = new Error(response.statusText); try { response.clone().json().then((result) => { error.body = result; error.response = response; reject(error); }); } catch (e) { error.response = response; reject(error); } }); }/* eslint-enable consistent-return */// sugerrequest.get = (url, options) => request(url, options, 'GET'); request.head = (url, options) => request(url, options, 'HEAD'); request.options = (url, options) => request(url, options, 'OPTIONS'); request.post = (url, options) => request(url, options, 'POST'); request.put = (url, options) => request(url, options, 'PUT'); request.delete = (url, options) => request(url, options, 'DELETE'); request.del = request.delete;export default request;
5. 这样你就可以在今后的项目正常使用按照以下步骤
module.exports = { apiBaseUrl: "http://172.118.100.50/api/", };
之后再services文件下就可以这样去下啦:
import request from '../utils/request/request';export function queryScaleMenu(start, limit) { const body = new FormData(); body.append('start',start); body.append('limit', limit); return request.post('news/menu/query', { body }); }
作者:sidney_c
链接:https://www.jianshu.com/p/007196101cf1
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦