写在前面:不喜勿喷
这是一篇vue3+ts的axios的开箱即用的文章,希望可以帮助到大家,如果大家不喜欢勿喷。
开箱及用
- 全局下载axios
- 封装axios的请求拦截器
- 编写api.ts
- 页面使用
- 配置vite.config.ts
1.在vue3的项目里面下载axios
构建vue3的项目
npm init vue
需要什么就安装什么就好了,在这里就不过多介绍了
npm i axios
2. 封装axios的请求拦截器
我一般习惯于在项目src下面建一个common文件夹然后在建一个utils文件夹里面在建一个request.ts来放我的文件,这个看个人习惯。
request.ts
import axios from "axios"
import type { AxiosRequestConfig, AxiosResponse,AxiosError } from 'axios'
import { Names } from './requestCom/env-name'//枚举
import { errorCodeType } from './requestCom/error-code'//请求错误代码
// console.log(import.meta.env.VITE_HTTP)
const service = axios.create({
//配置的跨域标识
baseURL: '/api4',
//请求头
headers: {},
//超时
timeout: 1000 * Names.TIME,
})
//请求拦截器
service.interceptors.request.use((config: AxiosRequestConfig) => {
return config
}, (error:AxiosError) => {
console.log(error, 'e')
})
//响应拦截器
service.interceptors.response.use((config: AxiosResponse) => {
const code = config.data['code'] || 200;
if (code == 200) {
return Promise.resolve(config.data)
} else {
const msg = errorCodeType(code)
ElMessage.error(msg)
return Promise.reject(config.data)
}
// return config;
}, (error:AxiosError) => {
console.log(error)
})
export default service
env-name.ts
export const enum Names {
TIME = 60,
}
error-code.ts
export const errorCodeType = (code: string | number): string => {
let errMessage: string = '未知错误'
let arr: any = [[400, '错误的请求'], [401, '未授权,请重新登录'], [403, '拒绝访问'], [404, '请求错误,未找到该资源'], [405, '请求方法未允许'], [408, '请求超时'], [500, '服务器端出错'], [501, '网络未实现'], [502, '网络错误'], [503, '服务不可用'], [504, '网络超时'], [505, 'http版本不支持该请求']]
let map = new Map(arr)
errMessage = map.get(code) ?? '未知错误'
return errMessage
}
3.编写公共api.ts文件
import request from "@/common/utils/request"
//列表
export function List(data) {
return request({
url: '/index.php',//连接
params:{//会在拦截器里面自动拼接
a:1,
b:2,
},
method: 'post',//请求方法
data: data,//参数
})
}
4. 页面使用
import { List } from './api.ts';
let data = async () => {
let {name} = await List()
console.log(name,'name')
};
data()
5.vite.config.ts
import { fileURLToPath, URL } from 'node:url'
import { defineConfig, loadEnv, ConfigEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import electron from "vite-plugin-electron"
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import postcsspxtoviewport from "postcss-px-to-viewport"
export default ({ mode }: ConfigEnv) => {
const env = loadEnv(mode, process.cwd())
return defineConfig({
plugins: [vue(), vueJsx(), electron({
entry: "electron/main.ts",
onstart: options => {
options.startup(['.', '--no-sandbox'])
}
}),
AutoImport({
imports: ['vue', 'vue-router', 'pinia'],
dts: 'src/auto-import.d.ts',
resolvers: [
ElementPlusResolver(),
IconsResolver({
prefix: 'Icon',
}),]
}),
Components({
dts: 'src/components.d.ts',
resolvers: [
ElementPlusResolver(),
IconsResolver({
enabledCollections: ['ep'],
}),],
}),
Icons({
autoInstall: true,
})
],
server: {
host: '0.0.0.0',
port: 80,
proxy: {
'/api4': {
// 这里的target里的url 应该是你环境变量配置的动态变量
target: env.VITE_HTTP,
ws: true,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api4/, '')
},
},
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
css: {
preprocessorOptions: {
less: {
charset: false,
}
},
postcss: {
plugins: [
postcsspxtoviewport({
unitToConvert: 'px',// 要转化的单位
viewportWidth: 1920,// 要转化的单位
unitPrecision: 6, // 转换后的精度,即小数点位数
propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
selectorBlackList: [], // 指定不转换为视窗单位的类名,
minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
replace: true, // 是否转换后直接更换属性值
landscape: false // 是否处理横屏情况
})
]
}
}
})
}
到这里大概就已经完成了可能中间有写的不够详细的地方,大家可以根据自己的情况在进行更改,最后最后就是不喜勿喷。