本文最后更新于:2023年10月1日 晚上
介绍
基于axios和mockjs封装,请先安装
其他不介绍了,直接看使用好了
详细流程
创建文件结构(不重要,可自己改)
src
http
axios
apis(存放全部api的文件夹)
demoModule.js(demo模块的api)
...js(xxx模块的api)
interceptor.js(axios拦截器)
instances.js(axios实例)
mock
interceptor.js(mock拦截器)
以下文件内容中使用到了element-ui中的Message组件,可自行替换
axios 下的 interceptor.js(axios拦截器-核心1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
import { clearToken, getToken } from '@/utils/handler-token' import { Message } from 'element-ui' import { router } from '@/router'
const baseBeforeFilter = req => (req.headers.token = getToken(), req)
const baseAfterFilter = ({ status, statusText, data: { msg, code, data } }) => { if (status !== 200) return Promise.reject(statusText || '响应失败') .catch(Message.error) if (code === -1) { clearToken() return router.push('/info') } if (code !== 200) return Promise.reject(msg || '操作失败') .catch(err => { Message.error(err) return Promise.reject(err) }) return data }
export { baseBeforeFilter, baseAfterFilter }
|
axios 下 instances.js(axios实例-核心2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| import axios from 'axios' import { baseAfterFilter, baseBeforeFilter } from '@/http/axios/interceptor'
const defaultBaseOptions = { timeout: 6000 } const getType = val => Object.prototype.toString.call(val)
const createAxiosInstance = (baseOptions, { beforeFilter = baseBeforeFilter, afterFilter = baseAfterFilter } = {}) => { const axiosInstance = axios.create(Object.assign({}, defaultBaseOptions, baseOptions)) axiosInstance.interceptors.request.use(beforeFilter) axiosInstance.interceptors.response.use(afterFilter) return options => { const waitInstance = (instanceOptions = {}) => { if (getType(instanceOptions) === '[object Function]') return axiosInstance(options) .then(instanceOptions, e => e) const { success, error = e => e, before = () => {}, after } = instanceOptions before() return axiosInstance(options) .then(success, error) .finally(after) } waitInstance.mock = ({ success, error, before, after } = {}) => ( targetMockHTTP => getType(targetMockHTTP) === '[object Promise]' || targetMockHTTP({ success, error, before, after }) )(MockHTTP(options)) return waitInstance } }
const MockHTTP = createAxiosInstance({ baseURL: '/mock' })
const BaseInstance = createAxiosInstance({ baseURL: '/api' })
const LocalInstance = createAxiosInstance({ baseURL: '/src/assets' })
const UserInstance = createAxiosInstance({ baseURL: '/api/user' })
export { BaseInstance, LocalInstance, UserInstance, }
|
axios 下 apis api文件(例子)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
import { BaseInstance } from '@/http/axios/interceptor'
const DemoAPI = name => BaseInstance({ url: '/demo', params: { name } })
export { DemoAPI }
|
mock 下的 interceptor.js(例子)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
import { mock } from 'mockjs'
mock(/\/mock\/demo/, 'get', { code: 200, msg: '操作成功!', data: [ { name: '123', age: 123 }, { name: '123', age: 123 }, ] })
|
使用介绍
基础使用
此时有如 api 如:/api/demo,先定义接口方法(axios > apis > xxx.js)
1 2 3 4 5 6 7
| const DemoAPI = name => BaseInstance({ url: '/demo', params: { name }, ... })
|
发出请求(真实地址:/api/demo?name=Xin-FAS)
返回的是正常的Promise对象,后续可以正常使用then或await,但是不能使用catch去处理后续错误,理由在下面
发出使用mock的拦截请求(真实地址:/mock/demo?name=Xin-FAS)
1
| DemoAPI('Xin-FAS').mock()
|
几个内置的生命周期
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| DemoAPI('Xin-FAS')({ success (data) { }, error (msg) { }, before () { }, after () { } })
|
关于业务上的错误后续处理
不能使用catch处理错误的原因在于,已经内置了错误处理,就算是DemoAPI('Xin-FAS')()直接使用也不会出现错误拦截,内置默认为.catch(e => e),所以要进行错误的后续操作需要写在error中
1 2 3 4 5 6 7
| DemoAPI('Xin-FAS')() .then(res => { }) .catch(err => { })
|
正确使用:
1 2 3 4 5
| DemoAPI('Xin-FAS')({ error: msg => { }, })
|
this 指向问题
在回调函数中使用普通函数存在this指向问题,this并不指向当前vue实例,所以要使用this需要使用箭头函数,如下写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| DemoAPI('Xin-FAS')({ success (data) { this.tableData = data }, before () { this.loading = true }, after () { this.loading = false } })
DemoAPI('Xin-FAS')({ success: data => { this.tableData = data }, before: () => this.loading = true, after: () => this.loading = false })
|
简写形式
当只需要使用到成功处理时,如获取字典列表,可以在第二个方法中直接写一个函数:
1 2 3 4 5 6 7 8 9 10 11 12
| DemoAPI('Xin-FAS')({ success: data => { this.tableData = data }, })
DemoAPI('Xin-FAS')(data => { this.tableData = data })
|
await 使用演示
因为返回的是promise对象,所以await正常使用
1
| const data = await DemoAPI('Xin-FAS')()
|
1 2 3 4 5
| const data = await DemoAPI('Xin-FAS')({ error () { } })
|
当出现await和回调一起使用时
1 2 3 4 5 6
| const data = await DemoAPI('Xin-FAS')({ success (data) { console.log(data) } }) console.log(data)
|
这是因为success中同then,需要返回后才能被后续接受
1 2 3 4 5 6 7
| const data = await DemoAPI('Xin-FAS')({ success (data) { console.log(data) return data } }) console.log(data)
|
1 2 3 4 5 6 7 8 9
| const data = DemoAPI('Xin-FAS')({ success (data) { console.log(data) return data } }) data.then(res => { console.log(res) })
|