vue3+ts使用axios开箱即用

2,008 阅读3分钟

写在前面:不喜勿喷

这是一篇vue3+ts的axios的开箱即用的文章,希望可以帮助到大家,如果大家不喜欢勿喷。

开箱及用

  1. 全局下载axios
  2. 封装axios的请求拦截器
  3. 编写api.ts
  4. 页面使用
  5. 配置vite.config.ts

1.在vue3的项目里面下载axios

构建vue3的项目

npm init vue

需要什么就安装什么就好了,在这里就不过多介绍了

npm i axios

2. 封装axios的请求拦截器

我一般习惯于在项目src下面建一个common文件夹然后在建一个utils文件夹里面在建一个request.ts来放我的文件,这个看个人习惯。

1675068201380.jpg 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 // 是否处理横屏情况
          })
        ]
      }
    }
  })
}


到这里大概就已经完成了可能中间有写的不够详细的地方,大家可以根据自己的情况在进行更改,最后最后就是不喜勿喷