目前,关于vue中使axios的作为前端和后端接口交互工具的用法文章,网络某博客上数不胜数。因为项目从0到1开始需要基于vite+vue3.0ts中封装axios,所以今天让小编来给大家安排axios整合vite+vue3.0+ts的具体封装步骤。记录一下自己封装步骤,跟着我的步伐,撸起来。。。
npm i axios
注意:这里的安装命令就是默认安装最新版本的axios
代码如下:
export const errorCodeType = function(code:string):string{
let errMessage:string = "未知错误"
switch (code) {
case 400:
errMessage = '错误的请求'
break
case 401:
errMessage = '未授权,请重新登录'
break
case 403:
errMessage = '拒绝访问'
break
case 404:
errMessage = '请求错误,未找到该资源'
break
case 405:
errMessage = '请求方法未允许'
break
case 408:
errMessage = '请求超时'
break
case 500:
errMessage = '服务器端出错'
break
case 501:
errMessage = '网络未实现'
break
case 502:
errMessage = '网络错误'
break
case 503:
errMessage = '服务不可用'
break
case 504:
errMessage = '网络超时'
break
case 505:
errMessage = 'http版本不支持该请求'
break
default:
errMessage = `其他连接错误 --${code}`
}
return errMessage
}
这里用到的element-plus大家可以参考其官网安装即可,传送门:element-plus官网
安装命令:
npm install element-plus --save
代码如下:
import axios from 'axios';
import { errorCodeType } from '@/script/utils/error-code-type';
import { ElMessage, ElLoading } from 'element-plus';
// 创建axios实例
const service = axios.create({
// 服务接口请求
baseURL: import.meta.env.VITE_APP_BASE_API,
// 超时设置
// timeout: 15000,
headers:{'Content-Type':'application/json;charset=utf-8'}
})
let loading:any;
//正在请求的数量
let requestCount:number = 0
//显示loading
const showLoading = () => {
if (requestCount === 0 && !loading) {
//加载中显示样式可以自行修改
loading = ElLoading.service({
text: "拼命加载中,请稍后...",
background: 'rgba(0, 0, 0, 0.7)',
spinner: 'el-icon-loading',
})
}
requestCount++;
}
//隐藏loading
const hideLoading = () => {
requestCount--
if (requestCount == 0) {
loading.close()
}
}
// 请求拦截
service.interceptors.request.use(config => {
showLoading()
// 是否需要设置 token放在请求头
// config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?';
for (const propName of Object.keys(config.params)) {
const value = config.params[propName];
var part = encodeURIComponent(propName) + "=";
if (value !== null && typeof(value) !== "undefined") {
// 对象处理
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
let params = propName + '[' + key + ']';
var subPart = encodeURIComponent(params) + "=";
url += subPart + encodeURIComponent(value[key]) + "&";
}
} else {
url += part + encodeURIComponent(value) + "&";
}
}
}
url = url.slice(0, -1);
config.params = {};
config.url = url;
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use((res:any) => {
hideLoading()
// 未设置状态码则默认成功状态
const code = res.data['code'] || 200;
// 获取错误信息
const msg = errorCodeType(code) || res.data['msg'] || errorCodeType('default')
if(code === 200){
return Promise.resolve(res.data)
}else{
ElMessage.error(msg)
return Promise.reject(res.data)
}
},
error => {
console.log('err' + error)
hideLoading()
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) + "异常";
}
ElMessage.error({
message: message,
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service;
auto-imports.d.ts放在src目录下
注意:需要安装yarn add unplugin-auto-import
或者npm i unplugin-auto-import -D
安装完重启项目
代码如下:
declare global {
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const customRef: typeof import('vue')['customRef']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const effectScope: typeof import('vue')['effectScope']
const EffectScope: typeof import('vue')['EffectScope']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const resolveComponent: typeof import('vue')['resolveComponent']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const toRaw: typeof import('vue')['toRaw']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useSlots: typeof import('vue')['useSlots']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
}
export {}
注意:需要安装npm i unplugin-vue-components -D
或者yarn add unplugin-vue-components
安装完重启项目
import '@vue/runtime-core'
declare module '@vue/runtime-core' {
export interface GlobalComponents {
ElCard: typeof import('element-plus/es')['ElCard']
ElCol: typeof import('element-plus/es')['ElCol']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElFooter: typeof import('element-plus/es')['ElFooter']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElMain: typeof import('element-plus/es')['ElMain']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRow: typeof import('element-plus/es')['ElRow']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
Loading: typeof import('element-plus/es')['ElLoadingDirective']
}
}
export {}
注意:需要安装npm i unplugin-icons
或者yarn add unplugin-icons
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import Icons from "unplugin-icons/vite";
import IconsResolver from "unplugin-icons/resolver";
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import { loadEnv } from 'vite';
import path from 'path';
// 路径
const pathSrc = path.resolve(__dirname,'src')
// https://vitejs.dev/config/
export default({ command, mode }) => {
return defineConfig({
plugins: [
vue(),
AutoImport({
// Auto import functions from Vue, e.g. ref, reactive, toRef...
// 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
imports: ["vue"],
// Auto import functions from Element Plus, e.g. ElMessage, ElMessageBox... (with style)
// 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox... (带样式)
resolvers: [
ElementPlusResolver(),
// Auto import icon components
// 自动导入图标组件
IconsResolver({
prefix: "Icon",
}),
],
dts: path.resolve(pathSrc, "auto-imports.d.ts"),
}),
// 自动导入 Element Plus 组件
Components({
resolvers: [
// Auto register icon components
// 自动注册图标组件
IconsResolver({
enabledCollections: ["ep"],
}),
// Auto register Element Plus components
ElementPlusResolver(),
],
dts: path.resolve(pathSrc, "components.d.ts"),
}),
// 图标
Icons({
autoInstall: true,
}),
],
server:{
host: '127.0.0.1',
//port: Number(loadEnv(mode, process.cwd()).VITE_APP_PORT),
port: 3000,
strictPort: true, // 端口被占用直接退出
https: false,
open: true,// 在开发服务器启动时自动在浏览器中打开应用程序
proxy: {
// 字符串简写写法
'^/api': {
target: mode==='development'?loadEnv(mode, process.cwd()).VITE_APP_DEV_URL:loadEnv(mode, process.cwd()).VITE_APP_PROD_URL,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
},
hmr:{
overlay: false // 屏蔽服务器报错
}
},
resolve:{
alias:{
'@': pathSrc,
}
},
css:{
// css预处理器
/*preprocessorOptions: {
scss: {
additionalData: '@import "@/assets/styles/global.scss";'
}
}*/
preprocessorOptions: {
less: {
charset: false,
additionalData: '@import "./src/assets/style/global.less";',
},
},
},
build:{
chunkSizeWarningLimit: 1500, // 分块打包,分解块,将大块分解成更小的块
rollupOptions: {
output:{
manualChunks(id) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString();
}
}
}
}
}
})
}
完整的环境变量配置文件.env.production
和.env.development
7.1、项目根目录的development文件内容如下
# 开发环境
VITE_APP_TITLE = "阿绵"
# 端口号
VITE_APP_PORT = "3000"
# 请求接口
VITE_APP_DEV_URL = "http://localhost:8088"
# 前缀
VITE_APP_BASE_API = "/api"
7.2、项目根目录下的production文件内容如下
# 开发环境
VITE_APP_TITLE = "阿绵"
# 端口号
VITE_APP_PORT = "3000"
# 请求接口
VITE_APP_DEV_URL = "http://localhost:8088"
# 前缀
VITE_APP_BASE_API = "/api"
注意:这里还有一个PageParams全局分页对象:
page-params.ts
代码如下:
// 全局统一分页参数类型声明
declare interface PageParams {
pageNum: number, pageSize: number, type?: Model, // 可选参数
readonly sort?: string // 只读可选参数
} interface Model { type?: string }
export default PageParams;
本篇讨论的主要内容是:
axios整合vite+vue3.0+ts的具体封装步骤,对于细节方面还没很细,可以扩展更深入封装它
更多的源码教程 访问一淘模板 56admin.com