在vue中封装详细的axios,下载方法以及对接口的管理

3 篇文章 0 订阅

axios的安装

npm install axios

axios的引入,新建一个request.js文件

import axios from 'axios'
import { Notification, MessageBox, Message, Loading } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from "@/utils/ruoyi";
import cache from '@/plugins/cache'
import { saveAs } from 'file-saver'
import Cookies from 'js-cookie'

let downloadLoadingInstance;
// 是否显示重新登录
export let isRelogin = { show: false };

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 对应国际化资源文件后缀
axios.defaults.headers['Content-Language'] = 'zh_CN'
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时
  timeout: 10000
})

// request拦截器
service.interceptors.request.use(config => {
  // 是否需要设置 token
  const isToken = (config.headers || {}).isToken === false
  // 是否需要防止数据重复提交
  const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
  if (getToken() && !isToken) {
    config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
  }
  // get请求映射params参数
  if (config.method === 'get' && config.params) {
    let url = config.url + '?' + tansParams(config.params);
    url = url.slice(0, -1);
    config.params = {};
    config.url = url;
  }
  if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
    const requestObj = {
      url: config.url,
      data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
      time: new Date().getTime()
    }
    const sessionObj = cache.session.getJSON('sessionObj')
    if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
      cache.session.setJSON('sessionObj', requestObj)
    } else {
      const s_url = sessionObj.url;                  // 请求地址
      const s_data = sessionObj.data;                // 请求数据
      const s_time = sessionObj.time;                // 请求时间
      const interval = 1000;                         // 间隔时间(ms),小于此时间视为重复提交
      if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
        const message = '数据正在处理,请勿重复提交';
        console.warn(`[${s_url}]: ` + message)
        return Promise.reject(new Error(message))
      } else {
        cache.session.setJSON('sessionObj', requestObj)
      }
    }
  }
  return config
}, error => {
  console.log(error)
  Promise.reject(error)
})

// 响应拦截器
service.interceptors.response.use(res => {
  // 未设置状态码则默认成功状态
  const code = res.data.code || 200;
  // 获取错误信息
  const msg = errorCode[code] || res.data.msg || errorCode['default']
  // 二进制数据则直接返回
  if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
    return res.data
  }
  if (code === 401) {
    if (!isRelogin.show && window.location.href.indexOf("redirect") < 0) {
      isRelogin.show = true;
      MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
        confirmButtonText: '重新登录',
        cancelButtonText: '取消',
        type: 'warning'
      }
      ).then(() => {
        isRelogin.show = false;
        store.dispatch('LogOut').then(() => {
          location.href = process.env.VUE_APP_CONTEXT_PATH + 'index'
        })
      }).catch(() => {
        isRelogin.show = false;
      });
    }
    return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
  } else if (code === 500) {
    Message({
      message: msg,
      type: 'error'
    })
    return Promise.reject(new Error(msg))
  } else if (code !== 200) {
    Notification.error({
      title: msg
    })
    return Promise.reject('error')
  } else {
    return res.data
  }
},
  error => {
    console.log('err' + error)
    let { message } = error;
    if (message == "Network Error") {
      message = "后端接口连接异常";
    }
    else if (message.includes("timeout")) {
      message = "系统接口请求超时";
    }
    else if (message.includes("Request failed with status code")) {
      message = "系统接口" + message.substr(message.length - 3) + "异常";
    }
    Message({
      message: message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

// 通用下载方法
export function download(url, params, filename) {
  downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
  return service.post(url, params, {
    transformRequest: [(params) => { return tansParams(params) }],
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    responseType: 'blob'
  }).then(async (data) => {
    const isLogin = await blobValidate(data);
    if (isLogin) {
      const blob = new Blob([data])
      saveAs(blob, filename)
    } else {
      const resText = await data.text();
      const rspObj = JSON.parse(resText);
      const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
      Message.error(errMsg);
    }
    downloadLoadingInstance.close();
  }).catch((r) => {
    console.error(r)
    Message.error('下载文件出现错误,请联系管理员!')
    downloadLoadingInstance.close();
  })
}

export default service

然后在项目目录创建一个.env.development文件,文件配置如下

ENV = 'development'

# 接口地址,注意协议,如果你没有配置 ssl,需要将 https 改为 http

#上线
#VUE_APP_BASE_API = 'http://212.222.38.178:9091'
#测试
VUE_APP_BASE_API = 'http://193.16822.98.33:9091'


VUE_APP_AUTO_API = 'http://193.168.98.32:8081'


# 是否启用 babel-plugin-dynamic-import-node插件
VUE_CLI_BABEL_TRANSPILE_MODULES = true

配置完成以后,就可以在src目录下创建api文件夹,这里就是存放各种接口方法的地方,比如我创建了一个baseInfo文件夹,在这个文件夹中有一个workoerMng.js文件,文件中有以下几个接口

import request from '../../request'

//列表接口
export function getList(params) {
	return request({
		url: '/cFaultBill/page',
		method: 'get',
		params
	})
}
//获取设备
export function getSheBei(params) {
	return request({
		url: '/cdevice/getNotSyncList',
		method: 'get',
		params
	})
}

//编辑
export function faultBillEdit(data) {
	return request({
		url: '/cFaultBill/edit',
		method: 'post',
		data
	})
}

export function getOptions(params) {
	return request({
		url: '/faultType/getFaultType',
		method: 'get',
		params
	})
}
// 添加
export function deviceAdd(data) {
	return request({
		url: '/cFaultBill/save',
		method: 'post',
		data
	})
}
//删除
export function deviceDel(id) {
	console.log('删除的id', id)
	return request({
		url: `/cFaultBill/delete?id=${id}`,
		method: 'get',
		// params: {
		// 	id: id
		// }
	})
}

当我们需要调用这些接口的时候,用起来也非常方便,比如我们页面创建时候,需要获取页面的不分页数据,那么直接用以下的方法直接调用就可以获取数据

    initData() {
      getList(this.listQuery).then((res) => {
        console.log("提交的form数据", res);
        this.tableData = res.records;//表格数据消息
        this.count = res.total;//一共多少条数据
      });
    },

如果需要向服务器发起增加数据的请求,直接调用增加的请求接口然后传递增加的数据,这是非常便捷的

deviceAdd(this.specsForm)
            .then((res) => {
              // this.$message({
              //   type: "success",
              //   message: "新增成功!",
              // });
              this.btnLoading = false;
              this.dialogFormVisible = false;
              this.initData();
            })
            .catch((err) => {
              console.log(err);
              this.btnLoading = false;
            });
        }

封装axios是非常必要的,这样有助于我们对于代码的维护,而且大大减少了我们的代码量,一次封装,团队可以永久使用

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
对于axios进行封装,可以用以下步骤: 1. 安装axios依赖:在项目根目录下运行 `npm install axios --save` 命令。 2. 创建一个axios实例:在src目录下创建一个api.js文件,在其编写如下代码: ``` import axios from 'axios' // 创建axios实例 const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // api的base_url timeout: 5000 // 请求超时时间 }) // request拦截器 service.interceptors.request.use( config => { // 在发送请求之前做些什么 return config }, error => { // 对请求错误做些什么 console.log(error) // for debug Promise.reject(error) } ) // respone拦截器 service.interceptors.response.use( response => { /** * code为非20000是抛错 可结合自己业务进行修改 */ const res = response.data if (res.code !== 20000) { Message({ message: res.message, type: 'error', duration: 5 * 1000 }) return Promise.reject('error') } else { return response.data } }, error => { console.log('err' + error) // for debug Message({ message: error.message, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) } ) export default service ``` 在axios实例,我们可以设置baseURL、timeout等属性,并且可以使用拦截器来拦截请求和响应,实现一些全局处理逻辑。 3. 在需要使用axios的地方引入api.js文件,例如在vue组件: ``` import request from '@/utils/api' export default { data() { return { list: [] } }, methods: { getData() { request({ url: '/api/list', method: 'get' }).then(response => { this.list = response.data }).catch(error => { console.log(error) }) } } } ``` 在组件使用request函数来发送请求,可以通过设置请求方法、url、参数等来发送请求,然后通过then方法来处理响应结果。 接口api的封装,可以将所有对后端的请求都统一管理,减少重复代码。可以在src目录下创建一个api文件夹,然后在其创建一个index.js文件,编写如下代码: ``` import request from '@/utils/api' export function getList(params) { return request({ url: '/api/list', method: 'get', params }) } export function addData(data) { return request({ url: '/api/add', method: 'post', data }) } export function updateData(data) { return request({ url: '/api/update', method: 'post', data }) } export function deleteData(id) { return request({ url: '/api/delete', method: 'post', params: { id } }) } ``` 在这个文件,我们可以将所有的请求函数都定义在这里,并且通过导出的方式暴露出来,这样在组件就可以直接引入这些函数来发送请求了。例如: ``` import { getList, addData, updateData, deleteData } from '@/api' export default { data() { return { list: [] } }, methods: { getData() { getList().then(response => { this.list = response.data }).catch(error => { console.log(error) }) }, add() { addData({ name: 'test', age: 20 }).then(response => { console.log(response) }).catch(error => { console.log(error) }) }, update() { updateData({ id: 1, name: 'test', age: 25 }).then(response => { console.log(response) }).catch(error => { console.log(error) }) }, del(id) { deleteData(id).then(response => { console.log(response) }).catch(error => { console.log(error) }) } } } ``` 在组件直接调用api.js定义的函数,就可以完成对后端接口的请求了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

多看书少吃饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值