聊聊vite+vue3.0+ts中如何封装axios?
3641
目前,关于vue中使用axios的作为前端和后端接口交互工具的用法文章,网络某博客上数不胜数。因为项目从0到1开始需要基于vite+vue3.0+ts中封装axios,所以今天让小编来给大家安排axios整合vite+vue3.0+ts的具体封装步骤。记录一下自己封装步骤,跟着我的步伐,撸起来。。。
1、安装axios
- npm i axios
注意:这里的安装命令就是默认安装最新版本的axios
2、封装请求错误代码提示error-code-type.ts
代码如下:
- 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
- }
3、封装request.ts
这里用到的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;
4、自动导入vue3相关函数(auto-imports.d.ts)
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 {}
5、自动导入Element Plus 相关函数(components.d.ts)
注意:需要安装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 {}
6、vite.config.ts文件配置
注意:需要安装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();
- }
- }
- }
- }
- }
- })
- }
7、使用axios封装
完整的环境变量配置文件.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"
8、在任何vue文件内使用接口:
注意:这里还有一个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的具体封装步骤,对于细节方面还没很细,可以扩展更深入封装它
本文网址:https://www.zztuku.com/index.php/detail-12978.html
站长图库 - 聊聊vite+vue3.0+ts中如何封装axios?
申明:本文转载于《掘金社区》,如有侵犯,请 联系我们 删除。
您还没有登录,请 登录 后发表评论!
提示:请勿发布广告垃圾评论,否则封号处理!!