在Vue中是如何封装axios

目录

  • 1、安装
  • 1、引入
  • 3、接口根地址
  • 4、使用事例
    • 4.1下载
    • 4.2get
    • 4.3post

1、安装
npm install axios; // 安装axios


1、引入
import axios from 'axios'


3、接口根地址
const baseUrl = API_BASE_URL // 由webpack的插件DefinePlugin注入webpackConfig.plugin('define').use(require('webpack/lib/DefinePlugin'), [{// NODE_ENV 环境变量,开发环境为: 'development', 为了保证测试环境打的包与生产环境一致,测试环境和生产环境都为'production''process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),// 当前应用的环境(开发环境为: 'dev',测试环境为: 'test', 生产环境为: 'prod')'process.env.APP_ENV': JSON.stringify(process.env.APP_ENV),// 后台接口请求地址'API_BASE_URL': JSON.stringify(config.meshProp('apiBaseUrl')),// 首页路径'APP_INDEX_PATH': JSON.stringify(indexPath),// 路由模式'APP_ROUTER_MODE': JSON.stringify(config.meshProp('routerMode')),// 是否使用Element组件库'APP_USE_ELEMENT': JSON.stringify(config.meshProp('useElement')),}])

config.js:配置一些系统名称,api根路径等
const path = require('path')const os = require('os')const packageName = 'focm' // 项目包名称const localIP = getLocalIP() // 本地IP地址module.exports = {// 默认配置default: {// 系统名称,用于设置页面 head 中 titleappName: 'xxxxx',// 是否为多页应用isMulti: false,// 是否支持移动端isMobile: false,// 是否使用Element组件库(https://element.eleme.cn/#/zh-CN/)useElement: true,// 路由模式(值为hash 或 history, 参考:https://router.vuejs.org/)routerMode: 'hash',// 接口请求根路径apiBaseUrl: '',....},// 开发环境的配置dev: {apiBaseUrl: '/api',host: localIP,port: 8080,autoOpenBrowser: true, // 是否自动打开浏览器writeToDisk: false, // 是否将生成的文件写入磁盘proxyTable: {'/api': {target: 'http://focm-web.focms.paas.test',changeOrigin: true}}},// 测试环境的配置test: {// 接口请求根路径apiBaseUrl: '/focm',outputRoot: path.resolve(__dirname, 'dist/test'),publish: {remoteHost: 'x.x.x.x',remotePort: '22',remoteUsername: 'qinglianshizhe',remotePassword: 'xxxxxx',remoteAppRoot: `/xxx/xxx/${packageName}`,webUrl: 'http://xxxxx.com/'}},// 生产环境的配置prod: {...}}// 获取本地IPfunction getLocalIP () {let interfaces = os.networkInterfaces()for(let devName in interfaces){let iface = interfaces[devName]for(let i=0; i
我们继续来封装axios
/** * 业务异常类 */class BusinessError extends Error {constructor (code, message, data) {super(message)this.code = codethis.name = 'BusinessError'this.data = https://www.it610.com/article/data}}/** * 系统异常类 */class SystemError extends Error {constructor (code, message, data) {super(message)this.code = codethis.name ='SystemError'this.data = https://www.it610.com/article/data}}// axios 配置axios.defaults.timeout = 10000axios.defaults.headers.post['Content-Type'] = 'application/json; charset=UTF-8'// 执行 POST 请求function post (option, vm) {option.method = 'POST'return http(option, vm)}// 执行 GET 请求function get (option, vm) {option.method = 'GET'return http(option, vm)}// 下载请求function download (option, vm) {option.method = option.method || 'GET'option.isDownload = trueoption.responseType = 'blob'return http(option, vm)}/*** 请求后台接口* @param option 参数* url: 请求路径(会拼接到baseUrl后面,“/” 开头)* data: 请求参数对象* timeout: 请求超时时间(默认为:10000,即10秒)* toastError: 自动提示业务异常信息,默认为true,为false时不自动提示* @param vm Vue对象(用于异常时自动toast提示异常信息)* @return {Promise} Promise对象*/function http (option, vm) {return new Promise((resolve, reject) => {let method = option.method || 'POST'let url = baseUrl + option.urllet timeout = option.timeout || 10000let headers = option.headers || {}let responseType = option.responseTypelet data = https://www.it610.com/article/{} // 可以在此设置默认值if (option.data) {if (option.data instanceof FormData) {headers['Content-Type'] = 'multipart/form-data'let formData = https://www.it610.com/article/option.dataObject.keys(data).forEach((key) => {formData.append(key, data[key])})data = https://www.it610.com/article/formData} else {data = { ...data, ...option.data }}}let requestOptions = { method, url, headers, timeout, responseType }if (method.toUpperCase() ==='GET') {requestOptions.params = data} else {requestOptions.data = https://www.it610.com/article/data}axios(requestOptions).then( (res) => {const contentDisposition = res.headers['content-disposition']// 文件下载if (contentDisposition &&(/filename\*=UTF-8''(.*)/.test(contentDisposition) || /filename="(.*)"/.test(contentDisposition))) { // 如果是文件下载const utf8Match = contentDisposition.match(/filename\*=UTF-8''(.*)/) // 匹配UTF-8的文件名const normalMatch = contentDisposition.match(/filename="(.*)"/) // 匹配普通英文文件名const filename = utf8Match ? decodeURIComponent(utf8Match[1]) : normalMatch[1]const blob = new Blob([res.data])const downloadElement = document.createElement('a')const href = https://www.it610.com/article/window.URL.createObjectURL(blob)downloadElement.href = hrefdownloadElement.download = filenamedocument.body.appendChild(downloadElement)downloadElement.click()document.body.removeChild(downloadElement)window.URL.revokeObjectURL(href)resolve(res)} else { // JSON信息getResponseInfo(res).then((resInfo) => {responseInfoHandle(resInfo, resolve, reject, option, vm, requestOptions)})}}, err => {errorhandle(err, reject, option, vm)}).catch(function (err) {errorhandle(err, reject, option, vm)})})}// 处理响应信息function responseInfoHandle (resInfo, resolve, reject, option, vm) {// 请求是否成功let isSuccess = resInfo.retCode === '200'// 状态码let code = resInfo.retCode// 描述信息let message = resInfo.retMsg || '请求失败!'// 数据let resData = https://www.it610.com/article/resInfo.data || {}if (isSuccess) { // 请求成功console.log(`[${option.method ||'POST'}]${option.url} 请求成功!\n请求参数:`, option.data, '\n响应结果:', resInfo)resolve(resData)} else { // 业务异常console.error(`[${option.method} || 'POST']${option.url} 请求失败!\n请求参数:`, option.data, '\n响应结果:', resInfo)let err = new BusinessError(code, message, resData)errorhandle(err, reject, option, vm)}}// 获取响应信息json对象function getResponseInfo (res) {return new Promise((resolve, reject) => {// 返回的信息let resInfo = res.dataif (resInfo instanceof Blob) {const reader = new FileReader()reader.readAsText(resInfo, 'utf-8')reader.onload = () => {resInfo = JSON.parse(reader.result)resolve(resInfo)}} else {resolve(resInfo)}})}/* 异常处理 */function errorhandle (err, reject, option, vm) {let error = nullif (err.name === 'BusinessError') {error = err} else {console.error(option.url, '请求失败!', err.code, err)error = new SystemError(500, '非常抱歉,系统出现错误,请稍后重试!')}console.log('error = ', error)if (vm) {if (error.name === 'BusinessError') { // 业务异常// 没有权限if (error.code === 'xxx') {error.ignore = trueif (!isShowUnauthorized) {vm.$popupAlert({title: '提示',message: '未登录或者会话已过期,请重新登录!',width: 330,height: 180,btnText: '重新登录',onOK: () => {isShowUnauthorized = false // 是否显示重新登录弹框设为true// 跳转到登录页面,登录成功后还跳转到原路径vm.$router.push({ name: 'login', params: { fromPath: vm.$route.fullPath } })vm.$eventBus.$emit('NO_AUTH_EVENT')}})isShowUnauthorized = true // 是否显示重新登录弹框设为true}error.ignore = true} else if (option.toastError !== false) {vm.$toast({ type: 'error', message: error.message })}} else { // 系统异常vm.$toast('网络异常!')}}reject(error)}export default {baseUrl,http,post,get,download}

apiPlugin.js,封装成plugin插件
import Vue from 'vue'import api from '@/assets/js/api.js'export default {install () {Vue.prototype.$api = api}}

main.js,注入插件
import ApiPlugin from './plugins/apiPlugin.js'// 后台接口插件Vue.use(ApiPlugin)


4、使用事例
4.1下载

this.$api.download({url: '/xxx/xxx/xxx',data: params}, this)


4.2get

this.$api.get({url: `/xxx/xxx/xx`,data: params}, this).then((res) => {console.log(res)})

【在Vue中是如何封装axios】
4.3post

this.$api.post({url: '/api/basicList/query',data: params}, this).then(res => {})

到这里axios的封装基本就完成了
到此这篇关于在Vue中是如何封装axios的文章就介绍到这了,更多相关在Vue中封装axios内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    推荐阅读