Vite4、Vue3、Axios 针对请求模块化封装搭配自动化导入(简单易用)

news2024/11/30 2:40:41

针对请求模块化封装搭配自动化导入(简单易用)

  • 目标目录
  • 目标代码
  • 前提
  • 步入正题
    • src / utils / index.js
    • src /api / index.js
    • src /api / request.js
    • src /api / service.js
    • src /api / utils.js
    • src /api / modules / demo.js
  • 自动化配置
    • vite.config.js
    • eslint 校验问题

1

作者GitHub:https://github.com/gitboyzcf 有兴趣可关注!!!

目标目录

1

目标代码

<script setup>
    // 在js中直接调用useRequest() 函数就可以获取到配置的接口
	const { API_DEMO_POST, API_DEMO_GET } = useRequest()
	// 使用非常简单
	API_DEMO_GET({page: 1, pageSize: 10}).then(res => {  
		// 请求返回结果
	})
</script>

接下来看下面配置👇

前提

这里用到的相关npm包

  • element-plus 在这里用到了消息提示
  • axios 网络请求库
  • vueuse Vue hooks库
  • nprogress 加载进度条
  • consola 好看的日志打印

以上包根据自己需求修改即可、可有可无

步入正题

src / utils / index.js

import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { ElMessage } from 'element-plus'
/**
 * 获取资源路径
 * @param {相对路径} relativePath
 *    如果要动态获取assets的文件文件夹下的images中的图片
 *      relativePath 传入 assets/images/name.png
 * @returns 文件所在路径
 */
const getStaticResource = (relativePath) => {
  return new URL(`../${relativePath}`, import.meta.url)
}

/**
 * 消息提示
 * @param {弹出消息类型=》 info error warning success loading } type
 * @param {弹出消息文本} message
 * @param {弹出时间} duration
 * @param {弹出消息偏移} offset
 */
const msg = (type, message, duration = 2000, offset = 90) => {
  ElMessage({
    message,
    type,
    duration,
    offset
  })
}

/**
 * 模块化方式处理 默认处理 modules文件夹下的所有js文件 内容以export default导出的文件
 * @param { 模块内容集合 } moduleContext
 * @returns modules集合
 */
const modulesHandle = (moduleContext = {}) => {
  if (!Object.keys(moduleContext).length) return
  const modules = {}
  Object.keys(moduleContext).forEach((v) => {
    for (let key in moduleContext[v].default) {
      modules[key] = moduleContext[v].default[key]
    }
  })
  return modules
}

export { getStaticResource, modulesHandle, NProgress, msg }

src /api / index.js

import { modulesHandle } from '@/utils'

const apis = modulesHandle(import.meta.glob('./modules/**/*.js', { eager: true }))
export const useRequest = () => apis

mport.meta.glob函数从文件系统导入多个模块,详情请看官网 https://cn.vitejs.dev/guide/features#glob-import

src /api / request.js

import { service } from './service'
function createRequest(service) {
  function request(config) {
  	// config 自定义配置
    // axios默认配置
    const configDefault = {
      baseURL: import.meta.env.VITE_APP_API_BASEURL, // 所有通过此配置的基础地址 在.env文件配置
      timeout: 15000, // 请求超时时间
      responseType: 'json', // 响应类型
      headers: {
        // 请求头配置...
      }
    }
    const requestConfig = Object.assign(configDefault, config)
    return service(requestConfig)
  }
  return request
}

export const request = createRequest(service)

src /api / service.js

import axios from 'axios'
import { httpLogError, requestError, throttleToLogin } from './utils'
import { msg, NProgress } from '@/utils'
import consola from 'consola'

export function createService() {
  const request = axios.create()
  request.interceptors.request.use(
    (request) => {
      NProgress.start()
      return request
    },
    (err) => {
      NProgress.done()
      return Promise.reject(err)
    }
  )

  request.interceptors.response.use(
    (response) => {
      NProgress.done()
      const dataAxios = response.data
      // 这个状态码是和后端约定的
      const { code, data } = dataAxios

      // 根据 code 进行判断
      if (code === undefined) {
        return dataAxios
      } else {
        // 目前和公司后端口头约定是字符串,以防万一强制转字符串
        switch (`${code}`) {
          // code === 200 | 2 代表没有错误
          case '200':
            consola.withTag(`${response.config.url}`).success()
            return data
          // code === 400001004 代表token 过期打回登录页
          case '400001004':
            throttleToLogin()
            break
          case '400':
            // 不是正确的 code
            return requestError(response)
          case '401':
            // 错误登录
            return throttleToLogin()
          default:
            // 不是正确的 code
            return requestError(response)
        }
      }
    }, 
    (error) => {
      NProgress.done()
      console.log(error)
      const status = error.response?.status
      switch (status) {
        // TODO 再考虑下怎么判断是跨域问题
        case undefined:
        case null:
          httpLogError(error, '网路错误或请求跨域')
          break
        case 400:
          httpLogError(error, '请求错误')
          break
        case 401:
          httpLogError(error, '未授权,请登录')
          break
        case 403:
          httpLogError(error, '拒绝访问')
          break
        case 404:
          httpLogError(error, `请求地址出错: ${error.response.config.url}`)
          break
        case 408:
          httpLogError(error, '请求超时')
          break
        case 500:
          httpLogError(error, '服务器内部错误')
          break
        case 501:
          httpLogError(error, '服务未实现')
          break
        case 502:
          httpLogError(error, '网关错误')
          break
        case 503:
          httpLogError(error, '服务不可用')
          break
        case 504:
          httpLogError(error, '网关超时')
          break
        case 505:
          httpLogError(error, 'HTTP版本不受支持')
          break
        default:
          httpLogError(error, '请求错误')
          break
      }
      msg('error', error.message)
      return Promise.reject(error)
    }
  )
  return request
}

export const service = createService()

src /api / utils.js

import { msg as nMsg } from '@/utils'
import consola from 'consola'

export const httpLogError = (error, msg) => {
  error.message = msg
  consola.error(new Error(msg))
}

export const requestError = (response) => {
  return new Promise((_, reject) => {
    const { data } = response
    const msg = `api请求出错 ${response.config.url}${data.message}`
    nMsg('error', msg)
    consola.error(new Error(msg))
    reject(data)
  })
}

src /api / modules / demo.js

import { request } from '@/api/request.js'
export default {
  API_DEMO_POST(data = {}) {
    return request({
      baseURL: '/mock/login',
      url: 'api/mock',
      method: 'post',
      data
    })
  },

  API_DEMO_GET(params = {}) {
    return request({
      url: '/demo/get',
      method: 'get',
      params
    })
  }
}

自动化配置

安装 unplugin-auto-import/vite插件 https://github.com/unplugin/unplugin-auto-import#readme

npm install unplugin-auto-import -D 
or
pnpm install unplugin-auto-import -D
or
yarn add unplugin-auto-import -D

vite.config.js

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'

export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      imports: [
        'vue',
        'vue-router',
        'pinia',
        {
          '@/api': ['useRequest']
        }
      ],
      // eslintrc: {
        // enabled: true, // Default `false`
        // filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
        // globalsPropValue: true // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
      }
    })
  ]
})

eslint 校验问题

在vue文件中直接使用时 vscode 报红 说未定义
err

  1. 上面 vite.config.js中注释部分放开,运行项目根据这个./.eslintrc-auto-import.json相对路径会生成该 js 文件 。 注:生成后 把 enabled属性改为 false 以免再次生成
  2. .在根目录的 eslintrc.cjseslint配置文件中添加下面代码👇
    module.exports = {
       // ...
      'extends': [
    	// ...
        './.eslintrc-auto-import.json'
      ]
    }
    






到这里就结束了,后续还会更新 前端 系列相关,还请持续关注!
感谢阅读,若有错误可以在下方评论区留言哦!!!

111



推荐文章👇

Vue3-Composition API 快速上手(简单易懂)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1299771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《PySpark大数据分析实战》-01.关于数据

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

VSCode安装与使用

VS Code 安装及使用 1、下载 进入VS Code官网&#xff1a;地址&#xff0c;点击 DownLoad for Windows下载windows版本 注&#xff1a; Stable&#xff1a;稳定版Insiders&#xff1a;内测版 2、安装 双击安装包&#xff0c;选择我同意此协议&#xff0c;再点击下一步 选择你…

jquery实现省市区三级联动

一、技术: 前端采用的是jsp页面 后端采用springmvc+mybatis+mysql8 效果图 二、cascadeSelect.jsp页面 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%String path = request.getContextPath();String basePath = r…

流程画布开发技术方案归档(G6)

&#x1f3a8; 在理想的最美好世界中&#xff0c;一切都是为最美好的目的而设。 —— 伏尔泰 如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; 一、技术选型 •从可维护性和可拓展性出发 •基本满足 1&#xff1a;链接: https://github.com/hukaibaihu/vue-org…

Java 手写设计HashMap源码,让面试官膜拜

Java 手写HashMap源码&#xff0c;让面试官膜拜 一&#xff0c;手写源码 这是一个模仿HashMap的put&#xff0c;get功能的自定义的MyHashMap package cn.wxs.demo;import java.io.Serializable; import java.util.*; import java.util.function.BiConsumer;class MyHashMap&…

【解密考研英语:Python数据分析与可视化】

解密考研英语&#xff1a;Python数据分析与可视化 背景数据集技术选型功能实现创新点 大家好&#xff0c;欢迎阅读我的CSDN博客&#xff01;今天我将分享一项有关考研英语真题的数据分析与可视化项目&#xff0c;希望对考研学子提供更有针对性的复习帮助。 背景 作为考研学子…

【TwinCAT学习笔记 1】TwinCAT开发环境搭建

写在前面 作为技术开发人员&#xff0c;开启任何一项开发工作之前&#xff0c;首先都要搭建好开发环境&#xff0c;所谓磨刀不误砍材工&#xff0c;一定要有耐心&#xff0c;一次不行卸载再装。我曾遇到过一个学生&#xff0c;仅搭建环境就用了两周&#xff0c;这个过程也是一…

Docker容器的可视化管理工具—DockerUI本地部署与远程访问

文章目录 前言1. 安装部署DockerUI2. 安装cpolar内网穿透3. 配置DockerUI公网访问地址4. 公网远程访问DockerUI5. 固定DockerUI公网地址 前言 DockerUI是一个docker容器镜像的可视化图形化管理工具。DockerUI可以用来轻松构建、管理和维护docker环境。它是完全开源且免费的。基…

3接上篇 我的自定义GPTs的改进优化 与物理世界连接成功 GPTs的创建与使用定义和执行特定任务的功能模块 通过API与外部系统或服务的交互

https://blog.csdn.net/chenhao0568/article/details/134875067?spm1001.2014.3001.5502 从服务器日志里看到请求多了一个“location” 23.102.140.123 - - [08/Dec/2023:14:02:20 0800] "GET /getWeather.php?location&locationNewYork HTTP/1.1" 200 337 &…

公式识别任务各个链条全部打通

目录 引言公式识别任务是什么&#xff1f;公式识别任务解决方案初探使用建议写在最后 引言 随着LaTeX-OCR模型转换问题的解决&#xff0c;公式识别任务中各个链条已经全部打通。小伙伴们可以放开膀子干了。 解决业界问题的方案&#xff0c;并不是单独训练一个模型就完事了&am…

Spring Bean基础

写在最前面: 本文运行的示例在我github项目中的spring-bean模块&#xff0c;源码位置: spring-bean 前言 为什么要先掌握 Spring Bean 的基础知识&#xff1f; 我们知道 Spring 框架提供的一个最重要也是最核心的能力就是管理 Bean 实例。以下是其原因&#xff1a; 核心组件…

data_loader返回的每个batch的数据大小是怎么计算得到的?

data_loader是一个通用的术语&#xff0c;用于表示数据加载器或数据批次生成器。它是在机器学习和深度学习中常用的一个概念。 一、data loader 数据加载器&#xff08;data loader&#xff09;是一个用于加载和处理数据集的工具&#xff0c;它可以将数据集划分为小批次&#…

Oracle 中换行chr(10)、回车chr(13)

一、前言 chr(n)&#xff1a;返回 ascii 值对应的字符。 ascii(char)&#xff1a;返回字符 char对应的ascii 值。 chr(n) 和 ascii(char) 作用刚好是相反的。 SQL> select chr(65) from dual; 控制台显示&#xff1a;ASQL> select ascii(A) from dual; 控制台显示&am…

Oracle高可用一家老小全在这里

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

FL Studio2024永久免费体验版下载

FL Studio中文绿色21版是一款无需要安装的汉化版本&#xff0c;它是一款非常专业的音频编辑软件&#xff0c;可以让你的音乐突破想象力的限制哦&#xff0c;FL Studio21中文版可以制作出不同音律的节奏&#xff0c;FL Studio内置众多电子合成音色&#xff0c;只Styrus可以让人激…

鸿蒙开发组件之ForEach列表

一、ForEach函数 ForEach函数是一个迭代函数&#xff0c;需要传递两个必须参数和一个可选参数。主要通过迭代来获取参数arr中的数据不断的生成单个Item来生成鸿蒙中的列表样式 二、先创建单个的Item的UI 通过嵌套Row与Column来实现单个Item的UI。例如图中没有折扣的可以看成一…

C++-引用和指针区别

文章目录 1.变量的组成2.指针2.1 定义2.2 使用指针操作变量2.3 为什么使用指针 3.引用3.1 定义3.2 引用注意事项 4.引用和指针的区别 1.变量的组成 变量的组成&#xff1a;变量地址&#xff0c;变量名&#xff0c;变量值 例&#xff1a; int i 12;2.指针 2.1 定义 指针用于存…

【Python】简单的翻译软件

用translate包和tkinter写一个简单的桌面翻译软件。 1、窗口设置&引入包&#xff1a; from tkinter import * from tkinter.ttk import * from tkinter.messagebox import * import translatewinTk() win.title(翻译) win.geometry("600x400")win.mainloop() …

【Linux系统编程】初步运用git工具

介绍&#xff1a; 使用git之前首先要先认识gitee/github&#xff0c;gitee/github是一个远程仓库网站。git是平台专门开发的一个操控工具&#xff0c;是一个开源的分布式版本控制系统&#xff0c;我们使用git工具来与gitee/github来取得联系。 git的推送使用&#xff1a; git既…

解决electron修改主进程后需要重启才生效

nodemon 是一种工具&#xff0c;可在检测到目录中的文件更改时通过自动重新启动节点应用程序来帮助开发基于 node.js 的应用程序 nodemon 特性 自动重新启动应用程序。检测要监视的默认文件扩展名。默认支持 node&#xff0c;但易于运行任何可执行文件&#xff0c;如 python、…