微信小程序 接口请求封装(axios、Promise)

微信小程序 接口请求封装

一、axios  utils/request/axios.js 

/**
 * Copyright © 2020-present LiuDanYang. All rights Reserved.
 */

const axios = (function () {
  class Axios {
    constructor() {
      this.defaults = {
        baseUrl: "",
      };
      this.interceptors = {
        request: new InterceptorManager(),
        response: new InterceptorManager(),
      };
    }

    wxRequest(c) {
      return new Promise((resolve, reject) => {
        c = this.interceptors.request.func(c);
        c.url = c.url.startsWith("http") ? c.url : c.baseUrl + c.url;
        c.success = (res) => {
          resolve(this.interceptors.response.func(res));
        };
        c.fail = (res) => {
          reject(this.interceptors.response.func(res));
        };
        wx.request(c);
      });
    }
  }

  Array.prototype.forEach.call(
    ["options", "get", "head", "post", "put", "delete", "trace", "connect"],
    function (m) {
      Axios.prototype[m] = function (url, data, config) {
        return this.wxRequest(
          merge(
            this.defaults,
            {
              url: url,
              method: m,
              data: data,
            },
            config || {}
          )
        );
      };
    }
  );

  class InterceptorManager {
    constructor() {
      this.func = function (data) {
        return data;
      };
    }
    use(fn) {
      this.func = fn;
    }
  }

  function merge(axiosDefaultConfig, data, config) {
    let cloneAxios = deepClone(axiosDefaultConfig);
    let cloneData = deepClone(data);
    let cloneConfig = deepClone(config);
    return Object.assign(cloneAxios, cloneData, cloneConfig);
  }

  // 深拷贝
  function deepClone(obj) {
    let _obj = JSON.stringify(obj),
      objClone = JSON.parse(_obj);
    return objClone;
  }

  return new Axios();
})();

export default axios;

二、封装文件 utils/request/index.js 

/**
 * Copyright © 2020-present LiuDanYang. All rights Reserved.
 */

import axios from "./axios";
// import { getToken } from "@u/auth";

/**
 * axios defaults 配置
 */
axios.defaults = {
  baseUrl: "http://rap2.taobao.org:38080/",
  timeout: 60000,
};

/**
 * 全局 请求拦截器, 支持添加多个拦截器
 * 例如: 配置token、添加一些默认的参数
 * `return config` 继续发送请求
 */
axios.interceptors.request.use(
  (config) => {
    // 设置Token
    if (config.method === "post") {
      config.data = {
        ...config.data,
        //access_token: getToken(),
        _t: Date.parse(new Date()) / 1000
      };
    } else if (config.method === "get") {
      config.params = {
        ...config.params,
        //access_token: getToken(),
        _t: Date.parse(new Date()) / 1000
      };
    }
    return config;
  },
  (error) => {
    // 做一些请求错误
    console.error(error);
    return Promise.reject(error);
  }
);

/**
 * 全局 响应拦截器, 支持添加多个拦截器
 * 例如: 根据状态码选择性拦截、过滤转换数据
 * @param {Object} res 请求返回的数据
 * @return {Promise<reject>}
 */
axios.interceptors.response.use(
  async (res) => {
    const { data, statusCode: status } = res;

    try {
      return await handleCode({ data, status });
    } catch (err) {
      return Promise.reject(err);
    }
  },
  (err) => {
    // 做一些请求错误
    console.error(err);
    return Promise.reject(err);
  }
);

/**
 * 处理 HTTP 状态码
 * @param data {Object} 请求返回的数据
 * @param status {String} HTTP状态码
 * @returns {Promise<never>|*}
 */
function handleCode({ data, status }) {
  const STATUS = {
    "200"() {
      return data;
    },
    "400"() {
      return Promise.reject(new Error("请求错误"));
    },
    "401"() {
      return Promise.reject(new Error("请求未授权"));
    },
    "403"() {
      return Promise.reject(new Error("拒绝请求"));
    },
    "500"() {
      return Promise.reject(new Error("服务器错误"));
    },
  };
  // 有状态码但不在这个封装的配置里,就直接返回错误
  return STATUS[status]
    ? STATUS[status]()
    : Promise.reject(new Error(data.data || "请求错误"));
}

export default axios;

三、管理接口文件 utils/request/xhr.js

/**
 * Copyright © 2020-present LiuDanYang. All rights Reserved.
 */

import axios from "./index";

/**
 * get 请求方式
 * @param url {String} 接口地址
 * @param params {Object} 接口参数
 * @returns {AxiosPromise}
 * @constructor
 */
export function mGet(url, params) {
  return new Promise((resolve, reject) => {
    axios
      .get(url, params)
      .then((res) => {
        resolve(res);
      })
      .catch((err) => {
        reject(err);
      });
  });
}

/**
 * post 请求方式
 * @param url {String} 接口地址
 * @param data {Object} 接口参数
 * @returns {AxiosPromise}
 * @constructor
 */
export function mPost(url, data) {
  return new Promise((resolve, reject) => {
    axios
      .post(url, data)
      .then((res) => {
        resolve(res);
      })
      .catch((err) => {
        reject(err);
      });
  });
}

/**
 * put 请求方式-用于修改全部数据
 * @param url {String} 接口地址
 * @param data {Object} 接口参数
 * @returns {AxiosPromise}
 * @constructor
 */
export function mPut(url, data) {
  return new Promise((resolve, reject) => {
    axios
      .put(url, data)
      .then((res) => {
        resolve(res);
      })
      .catch((err) => {
        reject(err);
      });
  });
}

/**
 * patch 请求方式-用于修改单项或多项数据
 * @param url {String} 接口地址
 * @param data {Object} 接口参数
 * @returns {AxiosPromise}
 * @constructor
 */
export function mPatch(url, data) {
  return new Promise((resolve, reject) => {
    axios
      .patch(url, data)
      .then((res) => {
        resolve(res);
      })
      .catch((err) => {
        reject(err);
      });
  });
}

/**
 * delete 请求方式
 * @param url {String} 接口地址
 * @param params {Object} 接口参数
 * @returns {AxiosPromise}
 */
export function mDelete(url, params) {
  return new Promise((resolve, reject) => {
    axios
      .delete(url, params)
      .then((res) => {
        resolve(res);
      })
      .catch((err) => {
        reject(err);
      });
  });
}

四、接口文件 api/home.js

/**
 * Copyright © 2020-present LiuDanYang. All rights Reserved.
 */

import { mPost } from "../utils/request/xhr";

const getArticleList = (params) => mPost("app/mock/262524/get/article/list", params);

export { getArticleList };

五、js 使用接口 index/index.js

/**
 * 数据源来自于rap2 mock数据,调用url: http://rap2.taobao.org:38080/app/mock/262524/get/article/list
 */
import { getArticleList } from "../api/home";

Page({
  data: {
    list: [], // 列表数据
    pages: 1, // 当前页数
    pageSize: 20, // 每页数据的个数
    isLoading: false, // 正在加载中...,默认 false,隐藏
    isLoadingMore: false, //没有更多内容了,默认 false,隐藏
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad() {
    this.loadData();
  },
  /**
   * 请求数据封装
   */
  loadData() {
    let t = this;
    let pages = t.data.pages,
      pageSize = t.data.pageSize;

    getArticleList({
      pages: pages,
      pageSize: pageSize,
    })
      .then((res) => {
        let resData = res.data; // 返回的数据
        let resNum = resData.length; // 返回的数据列表个数

        // 如果返回的数据列表个数小于每页数据的个数
        if (resNum < t.data.pageSize) {
          t.setData({
            isLoadingMore: true,
            isLoading: false,
            list: resData,
          });
        } else {
          t.setData({
            isLoadingMore: false,
            isLoading: true,
            list: resData,
          });
        }
      })
      .catch((err) => {
        console.log("封装请求错误返回", err);
      });
  },
});

具体根据自己的需求去修改

微信开发者工具:接口封装demo代码片段

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱宇阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值