>首页> IT >

全球百事通!聊聊vite+vue3.0+ts中如何封装axios?

时间:2022-08-18 20:47:06       来源:转载


【资料图】

目前,关于vue中使用axios的作为前端和后端接口交互工具的用法文章,网络某博客上数不胜数。因为项目从0到1开始需要基于vite+vue3.0+ts中封装axios,所以今天让小编来给大家安排axios整合vite+vue3.0+ts的具体封装步骤。记录一下自己封装步骤,跟着我的步伐,撸起来。。。(学习视频分享:vue视频教程)

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//显示loadingconst showLoading = () => {    if (requestCount === 0 && !loading) {        //加载中显示样式可以自行修改        loading = ElLoading.service({            text: "拼命加载中,请稍后...",            background: "rgba(0, 0, 0, 0.7)",            spinner: "el-icon-loading",        })    }    requestCount++;}//隐藏loadingconst 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的具体封装步骤,对于细节方面还没很细,可以扩展更深入封装它

(学习视频分享:web前端开发、编程基础视频)

以上就是聊聊vite+vue3.0+ts中如何封装axios?的详细内容,更多请关注php中文网其它相关文章!

关键词: 相关函数 需要安装 系统接口