uniapp和uview-plus组件在项目中向后端发起请求的封装
文章目录
- Http请求
- 请求方法说明
- 二、拦截器
- 1.请求拦截
- 2.响应拦截
- 应用实例
- export和export default的区别
Http请求
该插件适用于普遍的请求场景,支持post、get、put和delete,以及上传下载等请求,有如下特点:
- 基于Promise对象实现更简单的request使用方式,支持请求和响应拦截
- 支持全局挂载
- 支持多个全局配置实例
- 支持自定义验证器
- 支持文件上传/下载
- 支持task 操作
- 支持自定义参数
- 支持多拦截器
- 对参数的处理比uni.request更强
{
baseURL: '',
header: {},
method: 'GET',
dataType: 'json',
// #ifndef MP-ALIPAY
responseType: 'text',
// #endif
// 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部)
custom: {}, // 全局自定义参数默认值
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
timeout: 60000,
// #endif
// #ifdef APP-PLUS
sslVerify: true,
// #endif
// #ifdef H5
// 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+)
withCredentials: false,
// #endif
// #ifdef APP-PLUS
firstIpv4: false, // DNS解析时优先使用ipv4 仅 App-Android 支持 (HBuilderX 2.8.0+)
// #endif
// 局部优先级高于全局,返回当前请求的task,options。请勿在此处修改options。非必填
// getTask: (task, options) => {
// 相当于设置了请求超时时间500ms
// setTimeout(() => {
// task.abort()
// }, 500)
// },
// 全局自定义验证器。参数为statusCode 且必存在,不用判断空情况。
validateStatus: (statusCode) => { // statusCode 必存在。此处示例为全局默认配置
return statusCode >= 200 && statusCode < 300
}
}
请求方法说明
- GET请求
get请求与post请求略有不同,get请求所有参数都在方法的第二个参数中,而post请求的第二个参数为请求参数params,而第三个参数才为配置项。
局部修改配置,局部配置优先级高于全局配置import { http, toast} from '@/uni_modules/uview-plus' // 基本用法,注意:get请求的参数以及配置项都在第二个参数中 http.get('/user/login', {params: {userName: 'name', password: '123456'}}).then(res => { header: {}, /* 会与全局header合并,如有同名属性,局部覆盖全局 */ dataType: 'json', // 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部) custom: {auth: true}, // 可以加一些自定义参数,在拦截器等地方使用。比如这里我加了一个auth,可在拦截器里拿到,如果true就传token }).catch(err => { })
- POST请求
import { http, toast} from '@/uni_modules/uview-plus' // 基本用法,注意:post的第三个参数才为配置项 http.post('/user/login', {userName: 'name', password: '123456'} ).then(res => { params: {}, /* 会加在url上 */ header: {}, /* 会与全局header合并,如有同名属性,局部覆盖全局 */ dataType: 'json', // 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部) custom: {auth: true}, // 可以加一些自定义参数,在拦截器等地方使用。比如这里我加了一个auth,可在拦截器里拿到,如果true就传token }).catch(err => { })
- UPLOAD请求
具体参数说明:uni.uploadFileimport { http, toast} from '@/uni_modules/uview-plus' http.upload('api/upload/img', { params: {}, /* 会加在url上 */ // #ifdef APP-PLUS || H5 files: [], // 需要上传的文件列表。使用 files 时,filePath 和 name 不生效。App、H5( 2.6.15+) // #endif filePath: '', // 要上传文件资源的路径。 // 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部) custom: {auth: true}, // 可以加一些自定义参数,在拦截器等地方使用。比如这里我加了一个auth,可在拦截器里拿到,如果true就传token // #ifdef H5 || APP-PLUS timeout: 60000, // H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+) // #endif header: {}, /* 会与全局header合并,如有同名属性,局部覆盖全局 */ formData: {}, // HTTP 请求中其他额外的 form data // 返回当前请求的task, options。请勿在此处修改options。非必填 getTask: (task, options) => { // 返回上传进度 }, }).then(res => { // 返回的res.data 已经进行JSON.parse }).catch(err => { })
- DOWNLOAD请求
具体参数说明:uni.downloadFileimport { http, toast} from '@/uni_modules/uview-plus' http.download('api/download', { params: {}, /* 会加在url上 */ header: {}, /* 会与全局header合并,如有同名属性,局部覆盖全局 */ custom: {}, // 自定义参数 }).then(res => { }).catch(err => { })
二、拦截器
1.请求拦截
作用:发送请求的时候,携带一些信息:请求公共的参数,将来项目中【N个请求】,只要发请求,会触发请求拦截器。例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易。
import { http, toast} from '@/uni_modules/uview-plus'
/**
* 请求拦截
* @param {Object} http
*/
http.interceptors.request.use((config) => { // 可使用async await 做异步操作
// 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{}
config.data = config.data || {}
// console.log(store.state);
// 演示custom 用处 添加token
// if (config.custom.auth) {
// config.header.token = 'token'
// }
// if (config.custom.loading) {
// uni.showLoading()
// }
// 演示
// if (!token) { // 如果token不存在,return Promise.reject(config) 会取消本次请求
// return Promise.reject(config)
// }
return config
}, (config) => // 可使用async await 做异步操作
Promise.reject(config))
2.响应拦截
作用:当服务器手动请求之后,做出响应;接收到数据的时候,进行数据过滤、对状态码判断,进行对应的操作。
import { http, toast} from '@/uni_modules/uview-plus'
/**
* 响应拦截
* @param {Object} http
*/
http.interceptors.response.use((response) => { /* 对响应成功做点什么 可使用async await 做异步操作*/
const data = response.data
// 自定义参数
const custom = response.config?.custom
if (data.code !== 200) { // 服务端返回的状态码不等于200,则reject()
// 如果没有显式定义custom的toast参数为false的话,默认对报错进行toast弹出提示
if (custom.toast !== false) {
toast(data.message)
}
// 如果需要catch返回,则进行reject
if (custom?.catch) {
return Promise.reject(data)
} else {
// 否则返回一个pending中的promise
return new Promise(() => { })
}
}
return data.data || {}
}, (response) => { /* 对响应错误做点什么 (statusCode !== 200)*/
return Promise.reject(response)
})
应用实例
- 全局配置,以及请求,响应拦截器定义
在/common/config中
const config = {
baseUrl: 'http://192.168.0.78:8084'
}
export {
config
}
在/util/request/index.js中
// 引入参数配置
import {config} from '@/common/config'
// 引入拦截器配置
import {requestInterceptors,responseInterceptors} from './interceptors.js'
// 引入uview-plus
import { http } from 'uview-plus'
// 初始化请求配置
const initRequest=(vm)=>{
http.setConfig((defaultConfig) => {
/* defaultConfig 为默认全局配置 */
defaultConfig.baseURL = config.baseUrl /* 根域名 */
defaultConfig.loadingText = '努力加载中~'
defaultConfig.loadingTime = 800
return defaultConfig
})
requestInterceptors()
responseInterceptors()
}
export {
initRequest
}
```
2. 在/util/request/interceptors.js中,写入如下内容:
```javascript
import { http, toast} from 'uview-plus'
const requestInterceptors=(vm)=>{
/**
* 请求拦截
* @param {Object} http
*/
http.interceptors.request.use((config) => { // 可使用async await 做异步操作
// 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{}
config.data = config.data || {}
// 一般在这里配置 token
config.header['token'] = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJGT3JnX0NvZGY';
// 假的数据 稍等登录成功后然后把 token 存起来之后在获取
config.header['X-App-Platform'] = 'wxapp';
// console.log(config)
return config
}, (config) => // 可使用async await 做异步操作
Promise.reject(config))
}
const responseInterceptors=(vm)=>{
/**
* 响应拦截
* @param {Object} http
*/
http.interceptors.response.use((response) => { /* 对响应成功做点什么 可使用async await 做异步操作*/
const data = response.data
// 自定义参数
const custom = response.config?.custom
if (data.code != '0') {
// 服务端返回的状态码不等于0,则reject()
// 如果没有显式定义custom的toast参数为false的话,默认对报错进行toast弹出提示
if (custom.toast !== false) {
toast(data.message)
}
// 如果需要catch返回,则进行reject
if (custom?.catch) {
return Promise.reject(data)
} else {
// 否则返回一个pending中的promise
return new Promise(() => { })
}
}
return data.data || {}
}, (response) => { /* 对响应错误做点什么 (statusCode !== 200)*/
return Promise.reject(response)
})
}
export {
requestInterceptors,
responseInterceptors
}
```
3. 在/util/request/api.js中,写入如下内容:
封装post和get请求
```javascript
// 引入uview-plus
import { http } from 'uview-plus'
/**
* 请求组件封装
* url 请求地址
* data 请求参数
* contentType 请求内容类型 1 json 强求 2 form表单请求
*/
const post = (url, params, contentType = '1') => {
return new Promise((resolve, reject) => {
let header = {
'content-type': contentType == 1 ? 'application/json' : 'application/x-www-form-urlencoded'
}
http.post(url, params, header).then(res => {
resolve(res)
})
})
}
/**
* 请求组件封装
* url 请求地址
* data 请求参数
* contentType 请求内容类型 1 json 强求 2 form表单请求
*/
const get = (url, params) => {
console.log(url, params)
return new Promise((resolve, reject) => {
http.get(url, params).then(res => {
resolve(res)
})
})
}
export {post, get}
```
4. 引用配置
在main.js中引用/util/request/index.js,注意引用的位置,需要在new Vue得到Vue实例之后,如下:
```javascript
import App from './App'
// #ifdef VUE3
import * as Pinia from 'pinia';
import { createSSRApp } from 'vue'
import uviewPlus from 'uview-plus'
import {initRequest} from '@/util/request/index.js'
export function createApp() {
const app = createSSRApp(App)
// 引入请求封装
initRequest(app)
app.use(Pinia.createPinia());
app.use(uviewPlus)
return {
app,
Pinia,
}
}
// #endif
- Api集中管理
在/config/api.js中编写请求接口:
import {post, get} from '@/util/request/api.js'
let bannersApi = (params) => get('/jeecg-boot/sys/dict/getDictItems/bag_status', params);
export {
bannersApi
}
- Api集中管理
在页面中的应用
<script>
import {bannersApi} from '@/apis/index.js'
export default {
data() {
return {
};
},
onLoad(){
this.getbannerd()
},
methods: {
async getbannerd() {
const data = await bannersApi()
console.log(data)
}
}
};
export和export default的区别
export和export default是ES6中用于导出模块的关键字
- export关键字用于导出一个或多个变量、函数或类。可以使用export关键字将一个或多个变量、函数或类导出,以便其他模块可以使用它们。
// a.js中的定义
const a = '1'
const b = '2'
const c = '3'
export { a, b , c}
// js中的定义
import {a, b, c} from './a.js'
console.log(a, b, c) // '1' '2' '3'
- export default关键字用于导出一个默认的变量、函数或类。每个模块只能有一个默认导出
需要注意的是,导入默认导出时可以为其指定任意名称,而不需要使用花括号。这是因为默认导出是唯一的,所以可以直接使用导入的变量名。
// b.js中的定义
const a = '1'
const b = '2'
const c = '3'
export { a, b , c}
// js中的定义
import B from './b.js'
console.log(B.a, B.b, B.c) // '1' '2' '3'