一、简介
Vue封装axios请求是指将axios库集成到Vue项目中,以便更方便地发送HTTP请求。首先,需要安装axios库,然后在Vue项目中创建一个名为request.js的文件,用于封装axios实例。在这个文件中,可以设置默认的配置,如基础URL、超时时间等。接下来,可以定义一些常用的请求方法,如GET、POST等,并将这些方法导出,以便在Vue组件中使用。这样,每次发送请求时,只需调用封装好的方法即可,无需每次都写完整的axios代码。
二、代码实现
2.1 创建Vue2项目
-
创建项目
vue create vue-request
-
选项(选择自定义)
Vue CLI v5.0.8 ? Please pick a preset: Default ([Vue 3] babel, eslint) Default ([Vue 2] babel, eslint) > Manually select features 选自定义
-
手动选择功能
-
选择vue的版本
-
选择css预处理
-
选择配置文件的生成方式
-
是否保存预设,下次直接使用? => 不保存,输入 N
2.2 安装插件
npm install --save axios
npm install element-ui -S
// 或者
yarn add axios
yarn add element-ui
2.3 配置环境变量
项目路径下创建
.env.development
、.env.production
文件
-
.env.development
# 页面标题 VUE_APP_TITLE = 佳运管理系统 # 开发环境配置 ENV = 'development' # 开发环境 VUE_APP_BASE_API = '/dev-api'
-
.env.production
# 页面标题 VUE_APP_TITLE = 佳运管理系统 # 生产环境配置 ENV = 'production' # 生产环境 VUE_APP_BASE_API = '/prod-api'
2.4 配置vue.config.js文件
// 导入 Vue CLI 的配置工具
const { defineConfig } = require('@vue/cli-service')
// 使用 defineConfig 函数来定义项目的配置
module.exports = defineConfig({
// 指定是否对依赖进行转译。如果设置为 true,则所有依赖都会被 Babel 转译
transpileDependencies: true,
// 如果是生产环境则使用 /,否则也使用 /。如果部署到子路径下,需要修改为相应的子路径。
publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
// 构建输出目录的名称,默认是 dist
outputDir: 'dist',
// 配置生成的静态资源存放的目录
assetsDir: 'static',
// 是否开启eslint保存检测,有效值:ture | false | 'error'
lintOnSave: process.env.NODE_ENV === 'development',
// 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
productionSourceMap: false,
// webpack-dev-server 相关配置
devServer: {
// 设置开发服务器的主机地址,0.0.0.0 表示服务器监听所有 IP 地址
host: '0.0.0.0',
// 开发服务器使用的端口 --记得修改成自己的前端端口
port: 9000,
// 设置是否在启动服务器后自动打开浏览器
open: true,
// 配置代理规则,用于解决跨域问题
proxy: {
// 定义代理规则的前缀
[process.env.VUE_APP_BASE_API]: {
// 代理的后端目标地址
target: `http://localhost:8080`,
// 设置为 true 时,会改变请求的 origin 头,使得目标服务器能够正确响应
changeOrigin: true,
// 重写代理请求中的路径去掉前缀 VUE_APP_BASE_API
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''
}
}
}
}
})
2.5 封装axios实例
src
目录下创建utils
目录并在此目录下创建request.js
文件
// 导入axios库
import axios from 'axios'
// 导入Element UI的通知和消息组件
import {Notification, Message} from 'element-ui'
// 设置axios的默认请求头
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 10000
})
// request拦截器
service.interceptors.request.use(config => {
// 将请求体转换为JSON字符串
config.data = JSON.stringify(config.data);
// 返回配置对象以便继续发送请求
return config
}, error => {
// 如果发生错误,打印错误信息并拒绝Promise
console.log(error)
return Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态
const code = res.data.code || 200;
// 获取错误信息
const msg = res.data.msg
// 二进制数据则直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return res.data
}
// 如果状态码为500,则显示错误消息并拒绝Promise
if (code === 500) {
Message({message: msg, type: 'error'})
return Promise.reject(new Error(msg))
} else if (code !== 200) { // 如果状态码不是200,则显示通知并拒绝Promise
Notification.error({title: msg})
return Promise.reject('error')
} else { // 如果状态码为200,则返回响应数据
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)
}
)
// 导出配置好的axios实例
export default service
2.6 api解耦
src
目录下创建api
目录并在此目录下创建接口js
文件
import request from '@/utils/request'
// 查询部门列表
export function listDept(query) {
return request({
url: '/system/dept/list',
method: 'get',
params: query
})
}
// 查询部门详细
export function getDept(deptId) {
return request({
url: '/system/dept/' + deptId,
method: 'get'
})
}
// 新增部门
export function addDept(data) {
return request({
url: '/system/dept',
method: 'post',
data: data
})
}
// 修改部门
export function updateDept(data) {
return request({
url: '/system/dept',
method: 'put',
data: data
})
}
// 删除部门
export function delDept(deptId) {
return request({
url: '/system/dept/' + deptId,
method: 'delete'
})
}
2.7 使用api
// 引入js文件
import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept";
// 使用
methods: {
/** 查询部门列表 */
getList() {
this.loading = true;
listDept(this.queryParams).then(response => {
this.deptList = this.handleTree(response.data, "deptId");
this.loading = false;
});
},
/** 新增按钮操作 */
handleAdd(row) {
if (row != undefined) {
this.form.parentId = row.deptId;
}
this.open = true;
this.title = "添加部门";
listDept().then(response => {
this.deptOptions = this.handleTree(response.data, "deptId");
});
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
getDept(row.deptId).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改部门";
listDeptExcludeChild(row.deptId).then(response => {
this.deptOptions = this.handleTree(response.data, "deptId");
if (this.deptOptions.length == 0) {
const noResultsOptions = { deptId: this.form.parentId, deptName: this.form.parentName, children: [] };
this.deptOptions.push(noResultsOptions);
}
});
});
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.deptId != undefined) {
updateDept(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addDept(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
this.$modal.confirm('是否确认删除名称为"' + row.deptName + '"的数据项?').then(function() {
return delDept(row.deptId);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
}
}