封装小程序网络请求接口

312 阅读2分钟

小程序提供了异步请求的函数wx.request({}),很方便,但在实际使用上代码还是不够灵活。于是想起之前阿里大佬写的antd模板里面的例子就挺不错的,所以山寨了一份下来。 有些复杂的逻辑被我忽略了,有欠缺部分欢迎提出指点,好让小弟(小程序萌新)改进😁😁😁 首先是全局配置文件:根目录/config.js

export default {
  tabs: ['home', 'article', 'profile'],
  // 远端地址,上线切换
  // serverPath: 'https://xxx.com/xx/',
  // 本地地址
  serverPath: 'http://127.0.0.1:9090/wm/',
  // 图片服务器
  imagePath: 'https://xxx.com/xximg/',
}

请求工具:utils/request.js


import configs from '../config'

// 普通请求,文件下载请求类似这样写一个即可
export default function request(options) {
  /**
   * @param {object} data 传参
   * @param {string} method 请求方法
   * @param {string} url
   * @param {object} etcs request函数的其他属性,我暂时没用到
   */
  const { data, method, url, server, etcs } = options
  return new Promise(function (resolve, reject) {
    wx.request({
      // 如果是config之外的服务器地址,则自定义传入
      url: server ? server + url : configs.serverPath + url,
      method: method,
      ...etcs,
      data: data,
      success(response) {
        resolve({
          success: true,
          statusCode: response.statusCode,
          ...response.data
        })
      },
      fail(errors) {
        reject({
          error: true,
          success: false,
          statusCode: errors.statusCode
        })
      }
    })
  })
}

统一api集合:services/api.js

export default {
  queryArtical: 'api/wx/artical',
  getArtical: 'api/wx/artical/:id',
  updateArtical: 'PUT api/wx/artical/:id',
  createArtical: 'POST api/wx/artical',
  deleteArtical: 'DELETE api/wx/artical/:id'
}

请求构造器:services/index.js


import request from '../utils/request'
import api from './api'

/**
 * 用法
 */
// import call from '../../services/index'
// import api from '../../services/api'
// const { queryArtical } = api;
// const params = {};
// const result = call(queryArtical, { ...params });
// result.then(obj => {
//   console.log(obj);
// })

/**
 * 匹配URL中的动态传参,并转换为body中对应的值
 * @param {string} url
 * @param {object} body
 */
const catchDynamicParam = (url, body) => {
  // 带有":"的是动态传参
  const reg = new RegExp(/:(\w+)/g);
  const matches = url.match(reg);
  let keys = [];
  if (matches) {
    for (let param of matches) {
      const key = param.split(':')[1];
      const value = body[key];
      url = url.replace(param, value ? value : 'undefined');
      keys.push(key);
    }
  }
  const result = { url, keys };
  return result;
};

export default function call(query, params, server, etcs) {
  const matches = query.split(' ');
  let method;
  let url;
  if (matches.length > 1) {
    method = matches[0];
    url = matches[1];
  } else {
    // 默认都是get请求
    method = 'GET';
    url = matches[0];
  }

  const catcher = catchDynamicParam(url, params);
  url = catcher.url;
  const catchKeys = catcher.keys;
  for (const key of catchKeys) {
    // 把动态传参除外
    if (key in params) {
      delete params[key];
    }
  }

  return request({
    url: url,
    method: method,
    data: params,
    server: server,
    etcs: etcs
  });
}

使用

import call from '../../services/index'
import api from '../../services/api'
const { queryArtical } = api;
const params = {};
const result = call(queryArtical, { ...params });
result.then(obj => {
  console.log(obj);
})