UNPKG

@mypui/myp-ui

Version:

第一个高效且强悍的nvue开源组件库。做最好、最顺手的nvue组件库

292 lines (238 loc) 9.39 kB
# myp-request 简洁干脆的请求器。颗粒细,可配置和定制能力强。有任何问题可以加我`QQ:382006503`或者`微信:pptpdf``myp-request` 也就是以前的 `wakary-request`。 因为我们自己做了一套 `nvue` 页面 `uni-app` 模式下的 组件 `mypUI`,为了名字更加简短,改为 `myp-request`。 整个处理逻辑都比较`直接`,代码也比较`直白`,就是`简单粗暴`的去适配`uni.request`,并且支持`全局配置``独立覆盖`。 - 请求拦截,比如Header/URL配置检测、自动刷新Token等; - 响应拦截; - 在`uni.request`的回调中使用的全局callback; - api级别的callback; - 支持常规请求,上传以及下载; - 支持Promise以及Task; - 支持同步/异步; - 更多... # TODO - 被拦截时回掉处理也放入响应拦截器里面; > **注意:** > > 没有对`header`做细致的合并工作(不打算处理),也就是请求中的`header`配置是直接覆盖全局中的`header`配置,而不是差异合并(当然,如果你有特殊需求,可以在`请求拦截器`里面处理`header`)。 > > 不对`url`进行任何的检测(自己保证`url`的合法性),最终的`url`就是`baseUrl``api`配置中`url`的拼接(当然,你可以在拦截请求器里面修改`url`)。 > > 可以根据需要在构建接口时任意添加`参数/字段`,方便你在`拦截器`里面使用。 > > `请求被拦截`也会进入响应拦截器里面,而且会自动`reject`返回的内容,响应拦截器接收到的数据为`{mypCancel:true, response:...}`; > > 请求`fail`也会进入响应拦截器里面,而且会自动`reject`返回的内容,`fail`时响应拦截器接收到的数据为`{mypFail:true, response:...}`; > > `success/fail/complete`回掉并不对应`uni.request`,而是对应响应拦截器的处理逻辑,`resolve`对应`success``reject`对应`fail`; > > 不会`类axios`处理,不会进一步抽象与提炼。 # 使用 源码比较直白,可以看源码: - `Request`class对象,需要实例化; - 提供了一个`request`方法,`request`方法会调用您设置的`请求拦截器`,提前拦截; - 适配`uni.request`,完成 `request` 方法; - 请求取消或者失败会走`reject`(`catch`中处理); - 您可以通过`mypReqToReject`在响应拦截器中自由控制是否进入`reject`; - `fail`情况下也会进入响应拦截器,是否`fail`根据`response`中的`mypFail`来做判断; - `请求被拦截`也会进入响应拦截器,是否`被拦截`根据`response`中的`mypCancel`来做判断; ## 初始化请求器 自己可以新建一个 `request.js`,用来配置自己的请求器。 ```js // 引入 Request import Request from '@/mypUI/myp-request/index.js' // 设置 通用的 baseUrl 以及 header const config = { baseUrl: baseUrl, header: {"content-type": "application/x-www-form-urlencoded"} } // 设置自己的请求拦截器,必须加上 `async` // 请求前的拦截,比如是否登录/过期/刷新token/... const reqInterceptor = async (options) => { // 必须返回一个 Object // 拦截请求:return {mypReqToCancel: true, ...} // TODO: 添加任意拦截逻辑 return options } // 设置自己的响应拦截器 // 统一对返回的数据进行整理,方便接口统一使用 // conf是您api的options信息,一般情况下您只需要用到您自定义的标记字段 const resInterceptor = (response, conf={}) => { // 必须返回你需要处理的数据,将会进入resolve(then中处理) // 如果需要reject,需要设置mypReqToReject:true,还可以携带自己定义的任何提示内容(catch中处理) // uni.request进入fail也会进入该拦截器(为了统一处理逻辑),这个时候的response参数为{mypFail: true, response: fail info}。fail时不管返回啥,都进入reject(catch) if (response.mypFail) { return response.response } // 请求被拦截时也会进入该回掉(为了统一处理逻辑),这个时候的response参数为{mypCancel: true, response: cancel info}。cancel时不管返回啥,都进入reject(catch) if (response.mypCancel) { return response.response } return response } // 实例化请求器 // 您可以根据需要实例化多个请求器 const req = new Request(config, reqInterceptor, resInterceptor) export default req ``` ## 构建api或者直接使用 **我们使用了一些固定的参数来定义请求的类别:** - type: request-普通请求,upload-上传,download-下载; - task: 布尔值,是否返回task任务,默认是不返回 false; **我们使用了一些固定的参数来标记拦截状态:** - mypReqToCancel: 布尔值。请求拦截器的返回里标记是否拦截请求; - mypCancel: 布尔值。响应拦截器回掉参数中,标记请求是否被拦截; - mypFail: 布尔值。响应拦截器回掉参数中,标记是否进入了`uni.request`的`fail`,具体可以看拦截器示范; - mypReqToReject:布尔值。用于响应拦截器里面的返回内容标记,标记是否进入`reject`; ### 构建api ```js import request from '@/common/request.js' // baseUrl: 'https://www.baidu.com' // 在您需要请求的地方直接使用该api export function editInfo(data) { return request.request({ url: '/search', method: 'POST', data: data }) } ``` ```js import { editInfo } from '@/api/user.js' export default { methods: { changeUserInfo() { editInfo({name: 'nickname'}).then(res => { // success }).catch(err => { // error // err 有可能是 Error 对象,也有可能是 您自己定义的内容,处理的时候您需要自己判断 // 一个通用的错误提示组件就可以完成 }) } } } ``` ### 直接使用 ```js import request from '@/common/request.js' export default { methods: { changeUserInfo() { request.request({ url: '/edit_info', data: {name: 'nickname'}, method: 'POST' }).then(res => { // success }).catch(err => { // error }) } } } ``` 当然,您也可以在其它`js`中使用,比如`store`。 ## task ### api ```js export function upVideoProject(file, name, data={}, success=null, fail=null, complete=null) { return req.request({ url: '/projects/video_upload/', filePath: file, name: name, formData: data, type: 'upload', task: true }, success, fail, complete) } ``` ### 获取task **使用async/await获取** ```js try{ const a = await upVideoProject(this.videoSrc, 'video', {name: this.name.trim()}, (suc)=>{ // 其实就是resolve/then console.log('a success', suc) }, (fail) => { // 其实就是reject/catch console.log('a fail', fail) }, (com) => { // 通用逻辑 console.log('a complete', com) }) console.log('a task:', a) a.onProgressUpdate = (pg) => { console.log(pg.progress) } }catch(e){ //TODO handle the exception console.log('try:e:', e) } console.log('hi') ``` **then获取** ```js const a = upVideoProject(this.videoSrc, 'video', {name: this.name.trim()}, (suc)=>{ console.log('success', suc) }, (fail) => { console.log('fail', fail) }, (com) => { console.log('complete', com) }) console.log('task:', a) a.then(res => { console.log('res:', res) res.onProgressUpdate = (pg) => { console.log(pg.progress) } }).catch(err => { console.log('err:', err) }) console.log('hello') ``` ## success/fail/complete回掉 - `success/fail/complete`都支持全局配置和局部配置,全局和局部并不是覆盖关系,而是都会运行。先运行全局配置,然后是局部配置; - 所有的回掉都有一个参数,该参数就是响应拦截器里面您的返回内容; - `success/fail/complete`回掉并不对应`uni.request`的相应回掉,而是对应您的业务逻辑,`resolve/then`的就是`success`,`reject/catch`的就是`fail`; - `task`任务中,业务处理在`success/fail/complete`回掉中,毕竟不再是常规的`then/catch`处理; ### 全局配置 ```js const sucH = (res)=>{} ... const req = new Request(config, reqInter, resInter, sucH, failH, comH) ``` ### 局部配置 参考上面的task api处理方式。 # 建议 在构建`api`或者使用`request`的时候,您可以根据需要在`参数`里面增加字段,这样您可以根据自己的字段在`拦截器`里面做更多的事情。 ## 比如 ```js export function login(data) { return request.request({ url: '/login', method: 'POST', data: data, authType: 'None' }) } ``` 我们在`options`里面增加了一个`authType`参数,这样我们在构建`拦截器`的时候可以根据这个参数来判断该接口是否需要`登录授权`。 ```js // 需要登录的拦截掉,不需要登录的通过请求 const reqInterceptor = async (options) => { if (options.authType === 'None') { return options } return false } ``` # 更多 这就是一个最简单直接的请求库,你可以查看源码,从而根据自己的需要构建一个满意的`拦截器`和`响应器`。 其实就是根据你的接口配置信息以及拦截返回的数据进行判断,进一步去适配`uni.request`。 一切需要的都可以通过拦截器来实现。 # `mypUI` 全新的 `nvue-uniapp` 组件,一套组件支持编译到 `mp/h5/app`。 QQ群:`306797275` 有任何问题可以加`QQ:382006503`或者`微信:pptpdf`。