Home > Web Front-end > Vue.js > Let's talk about how to encapsulate axios in vite+vue3.0+ts?

Let's talk about how to encapsulate axios in vite+vue3.0+ts?

青灯夜游
Release: 2022-08-18 20:34:19
forward
2940 people have browsed it

Let's talk about how to encapsulate axios in vite+vue3.0+ts?

Currently, there are countless articles on the use of axios as a front-end and back-end interface interaction tool in Vue, and there are countless articles on a certain blog on the Internet. Because the project needs to be packaged in axios based on vite vue3.0 ts from 0 to 1, today I will let the editor arrange the specific packaging steps for axios to integrate vite vue3.0 ts. Record your own encapsulation steps, follow my steps, and get started. . . (Learning video sharing: vue video tutorial)

The following content is based on the expansion after the completion of the video below:

2021 Latest and Most Detailed Vite vue3 Volar Ts Element-plus framework learning project video

1. Install axios

npm i axios
Copy after login

Note: Installation here The command is to install the latest version of axios by default

2. Encapsulation request error code prompt error-code-type.ts

  • The code is as follows:
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
}
Copy after login

3. Encapsulate request.ts

You can refer to its official website to install the element-plus used here. Portal:

element-plus official website

安装命令:
npm install element-plus --save
Copy after login
  • The code is as follows:
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;
Copy after login

4. Automatically import vue3 related functions (auto-imports. d.ts)

  • auto-imports.d.ts is placed in the src directory
  • Note: yarn add unplugin-auto-import or npm i unplugin- needs to be installed auto-import -D
  • Restart the project after installation
  • The code is as follows:
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 {}
Copy after login

5. Automatically import Element Plus related functions (components.d.ts )

  • Note: You need to install npm i unplugin-vue-components -D or yarn add unplugin-vue-components
  • Restart the project after installation
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 {}
Copy after login

6, vite.config.ts file configuration

  • Note: need to install npm i unplugin-icons or 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();
                        }
                    }
                }
            }
        }
    })
}
Copy after login

7. Use axios package

Complete environment variable configuration files .env.production and .env.development

7.1. The content of the development file in the project root directory is as follows

# 开发环境
VITE_APP_TITLE = "阿绵" 
# 端口号 
VITE_APP_PORT = "3000" 
# 请求接口 
VITE_APP_DEV_URL = "http://localhost:8088" 
# 前缀 
VITE_APP_BASE_API = "/api"
Copy after login

7.2. The content of the production file in the project root directory is as follows

# 开发环境 
VITE_APP_TITLE = "阿绵" 
# 端口号 
VITE_APP_PORT = "3000" 
# 请求接口 
VITE_APP_DEV_URL = "http://localhost:8088" 
# 前缀 
VITE_APP_BASE_API = "/api"
Copy after login

8. Use the interface in any vue file:

  • Note: There is also a PageParams global paging object:

  • page-params.ts

  • The code is as follows:

// 全局统一分页参数类型声明 
declare interface PageParams {
    pageNum: number, pageSize: number, type?: Model, // 可选参数 
    readonly sort?: string // 只读可选参数 
} interface Model { type?: string }
export default PageParams;
Copy after login

Summary

This discussion The main content is:

  1. axiosThe specific packaging steps for integrating vite vue3.0 ts are not very detailed yet, and can be expanded to encapsulate it more deeply

(Learning video sharing: web front-end development, Basic programming video)

The above is the detailed content of Let's talk about how to encapsulate axios in vite+vue3.0+ts?. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:juejin.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template