uni-app request 封装

1,364 阅读3分钟

最近基于uni-app 做了个项目,有参考网络上一些人的做法,发现有的人每个page页面的请求都是直接uni.request不做二次封装,导致代码冗余,这里我想想给 uni.request封装下得了,来我们开始。。。。

不说了直接贴代码

创建文件request.js

/**
 * Request 1.0.0
 * @Class Request
 */
export default class Request {
	config = {
		baseUrl: '/',
		header: {
			'content-type': 'application/json;charset=UTF-8'
		},
		method: 'GET',
		dataType: 'json',
		// #ifndef MP-ALIPAY || APP-PLUS
		responseType: 'text',
		// #endif
		custom: {},
		// #ifdef MP-ALIPAY
		timeout: 30000,
		// #endif
		// #ifdef APP-PLUS
		sslVerify: true
		// #endif
	}
	
	// 判断url是否为绝对路径
	static posUrl(url) {
		return /(http|https):\/\/([\w.]+\/?)\S*/.test(url)
	}

	static addQueryString(params) {
		let paramsData = ''
		Object.keys(params).forEach(function(key) {
			paramsData += key + '=' + encodeURIComponent(params[key]) + '&'
		})
		return paramsData.substring(0, paramsData.length - 1)
	}

	//拦截器
	interceptor = {
		request: (cb) => {
			if (cb) {
				this.requestBeforeFun = cb
			}
		},
		response: (cb, ecb) => {
			if (cb && ecb) {
				this.requestComFun = cb
				this.requestComFail = ecb
			}
		}
	}

	requestBeforeFun(config) {
		return config
	}

	requestComFun(response) {
		return response
	}

	requestComFail(response) {
		return response
	}


	//自定义验证器
	validateStatus(statusCode) {
		return statusCode === 200
	}


	// 设置全局默认配置
	setConfig(f) {
		this.config = f(this.config)
	}

	//请求
	async request(options = {}) {
		options.baseUrl = this.config.baseUrl
		options.dataType = options.dataType || this.config.dataType
		// #ifndef MP-ALIPAY || APP-PLUS
		options.responseType = options.responseType || this.config.responseType
		// #endif
		// #ifdef MP-ALIPAY
		options.timeout = options.timeout || this.config.timeout
		// #endif
		options.url = options.url || ''
		options.data = options.data || {}
		options.params = options.params || {}
		options.header = options.header || this.config.header
		options.method = options.method || this.config.method
		options.custom = { ...this.config.custom,
			...(options.custom || {})
		}
		// #ifdef APP-PLUS
		options.sslVerify = options.sslVerify === undefined ? this.config.sslVerify : options.sslVerify
		// #endif
		return new Promise((resolve, reject) => {
			let next = true

			let handleRe = {}
			options.complete = (response) => {
				response.config = handleRe
				if (this.validateStatus(response.statusCode)) { // 成功
					response = this.requestComFun(response)
					resolve(response)
				} else {
					response = this.requestComFail(response)
					reject(response)
				}
			}
			const cancel = (t = 'handle cancel', config = options) => {
				const err = {
					errMsg: t,
					config: config
				}
				reject(err)
				next = false
			}

			handleRe = { ...this.requestBeforeFun(options, cancel)
			}
			const _config = { ...handleRe
			}
			if (!next) return
			delete _config.custom
			let mergeUrl = Request.posUrl(_config.url) ? _config.url : (_config.baseUrl + _config.url)
			if (JSON.stringify(_config.params) !== '{}') {
				const paramsH = Request.addQueryString(_config.params)
				mergeUrl += mergeUrl.indexOf('?') === -1 ? `?${paramsH}` : `&${paramsH}`
			}
			_config.url = mergeUrl
			uni.request(_config)
		})
	}
	//get请求
	get(url, data = {}, options = {}) {
		return this.request({
			url,
			data,
			method: 'GET',
			...options
		})
	}
	// post json
	post(url, data, options = {}) {
		this.config.header['content-type'] = 'application/json;charset=UTF-8'
		return this.request({
			url,
			data,
			method: 'POST',
			...options
		})
	}
	//post form表单
	postForm(url, data, options = {}) {
		this.config.header['content-type'] = 'application/x-www-form-urlencoded'
		return this.request({
			url,
			data,
			method: 'POST',
			...options
		})
	}
	// #ifndef MP-ALIPAY
	put(url, data, options = {}) {
		return this.request({
			url,
			data,
			method: 'PUT',
			...options
		})
	}

	// #endif

	// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
	delete(url, data, options = {}) {
		return this.request({
			url,
			data,
			method: 'DELETE',
			...options
		})
	}

	// #endif

	// #ifdef APP-PLUS || H5 || MP-WEIXIN
	connect(url, data, options = {}) {
		return this.request({
			url,
			data,
			method: 'CONNECT',
			...options
		})
	}

	// #endif

	// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
	head(url, data, options = {}) {
		return this.request({
			url,
			data,
			method: 'HEAD',
			...options
		})
	}

	// #endif

	// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
	options(url, data, options = {}) {
		return this.request({
			url,
			data,
			method: 'OPTIONS',
			...options
		})
	}

	// #endif

	// #ifdef APP-PLUS || H5 || MP-WEIXIN
	trace(url, data, options = {}) {
		return this.request({
			url,
			data,
			method: 'TRACE',
			...options
		})
	}

}

创建http.js文件

import Request from './request'

import Vue from 'vue';
const http = new Request()

http.setConfig((config) => { /* 设置全局配置 */
	config.baseUrl = '域名' /* 根域名不同 */
	config.header = {
		...config.header
	}
	return config
})

/**
 * 自定义验证器,如果返回true 则进入响应拦截器的响应成功函数(resolve),
 * 否则进入响应拦截器的响应错误函数(reject)
 * @param { Number } statusCode - 请求响应体statusCode(只读)
 * @return { Boolean } 如果为true,则 resolve, 否则 reject
 */
http.validateStatus = (statusCode) => {
	return statusCode === 200
}

http.interceptor.request((config, cancel) => { /* 请求之前拦截器 */
	config.header = {
		...config.header
	}
	/*
	if (!token) { // 如果token不存在,调用cancel 会取消本次请求,但是该函数的catch() 仍会执行
	  cancel('token 不存在') // 接收一个参数,会传给catch((err) => {}) err.errMsg === 'token 不存在'
	}
	*/
	return config
})

http.interceptor.response((response) => { /* 请求之后拦截器 */
	if (response.data.code === 401) { // token失效
		uni.redirectTo({
			url: '/pages/login/login'
		});
		return
	}
	if (response.data.code !== 0) { // 服务端返回的状态码不等于0,则reject()
		uni.showToast({
			icon: 'none',
			title: response.data.msg
		});
		return Promise.reject(response);
	}
	// if (response.config.custom.verification) { // 演示自定义参数的作用
	//   return response.data
	// }
	return response.data;
}, (response) => { // 请求错误做点什么
	return response
})
Vue.http = Vue.prototype.$http = http;
export default http

创建api.js 文件

import http from '@/http.js';
export default {
	/**
	 * login
	 * @param {*} params 
	 */
	login(params) {
		return http.postForm('/app/login', params)
	}
}

页面调用

import api from "@/api/api.js";
methods:{
   api.login(this.form).then(res => {
        if (res.code == 0) {
            //code....
        }
    }).catch(err => {
        //
    })
}

简单封装 如上。。。。哈哈,,如觉得有用,就留个言吧!!!