Vue3 + TS + Antd + Pinia 从零搭建后台系统(二) Ajax + Router

书接上回,接着填充。。。。此篇包含Ajax请求及router路由填充准备工作,在src文件夹下创建文件夹:api axios router

文章目录

  • axios填充
  • router填充

axios填充

规范一点,我们使用interface规范数据,创建一个types文件

import type {InternalAxiosRequestConfig,AxiosResponse,AxiosRequestConfig,AxiosInstance,AxiosRequestHeaders,AxiosError,
} from "axios";interface RequestInterceptors<T> {// 请求拦截requestInterceptors?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig;requestInterceptorsCatch?: (err: any) => any;// 响应拦截responseInterceptors?: (config: T) => T;responseInterceptorsCatch?: (err: any) => any;
}interface RequestConfig<T = AxiosResponse> extends AxiosRequestConfig {interceptors?: RequestInterceptors<T>;
}export {AxiosResponse,RequestInterceptors,RequestConfig,AxiosInstance,InternalAxiosRequestConfig,AxiosRequestHeaders,AxiosError,
};
在asios文件夹下创建 service.ts 、index.ts、 config.ts

service.ts

import axios from "axios";
import { defaultRequestInterceptors, defaultResponseInterceptors } from "./config";
import { AxiosInstance, InternalAxiosRequestConfig, RequestConfig, AxiosResponse } from "./types";
import { message } from "ant-design-vue";
import { useUserStoreWithOut } from "../pinia/user";
import Spin from "@/components/SpinLoader/loading";
// 获取配置的请求路径baseURL
export const PATH_URL = import.meta.env.VITE_API_BASE_PATH;const abortControllerMap: Map<string, AbortController> = new Map();const axiosInstance: AxiosInstance = axios.create({timeout: 60000,baseURL: PATH_URL,
});axiosInstance.interceptors.request.use((res: InternalAxiosRequestConfig) => {Spin.show(); // 后续文章中具体写全局loading设置const controller = new AbortController();const url = res.url || "";res.signal = controller.signal;abortControllerMap.set(url, controller);return res;
});axiosInstance.interceptors.response.use((res: AxiosResponse) => {Spin.hide();const url = res.config.url || "";abortControllerMap.delete(url);// 这里不能做任何处理,否则后面的 interceptors 拿不到完整的上下文了return res;},(error: any) => {Spin.hide();// 根据后端返回的值进行区分console.log("err: " + error); // for debugif (error?.response?.data?.status === 401) {const userStore = useUserStoreWithOut();userStore.logout();// 后续更新公共方法及全局方法message.error("登录失效,请重新登录");} else if (error?.response?.data?.status === 400) {message.error("数据有误,请确认正确后重新操作");} else {message.error(error.message);}return Promise.reject(error);}
);axiosInstance.interceptors.request.use(defaultRequestInterceptors);
axiosInstance.interceptors.response.use(defaultResponseInterceptors);const service = {request: (config: RequestConfig) => {return new Promise((resolve, reject) => {if (config.interceptors?.requestInterceptors) {config = config.interceptors.requestInterceptors(config as any);}axiosInstance.request(config).then((res) => {resolve(res);}).catch((err: any) => {reject(err);});});},cancelRequest: (url: string | string[]) => {const urlList = Array.isArray(url) ? url : [url];for (const _url of urlList) {abortControllerMap.get(_url)?.abort();abortControllerMap.delete(_url);}},cancelAllRequest() {for (const [_, controller] of abortControllerMap) {controller.abort();}abortControllerMap.clear();},
};export default service;

index.ts

import service from "./service";
import { useUserStoreWithOut } from "../pinia/user";
import { RawAxiosRequestHeaders } from "axios";type AxiosMethod = "get" | "post" | "delete" | "put";type AxiosResponseType = "arraybuffer" | "blob" | "document" | "json" | "text" | "stream";
interface AxiosConfig {params?: any;data?: any;url?: string;method?: AxiosMethod;headers?: RawAxiosRequestHeaders;responseType?: AxiosResponseType;
}
interface IResponse<T = any> {code: number;data: T extends any ? T : T & any;
}
// userStore.getToken在后续文章中介绍Pinia中更新获取token的方法
const request = (option: AxiosConfig) => {const { url, method, params, data, headers, responseType } = option;const userStore = useUserStoreWithOut();return service.request({url: url,method,params,data,responseType: responseType,headers: {"Content-Type": "application/json;charset=UTF-8",[userStore.getTokenKey ?? "Authorization"]: userStore.getToken ?? "",token: userStore.getToken ?? "",...headers,},});
};export default {get: <T = any>(option: AxiosConfig) => {return request({ method: "get", ...option }) as Promise<IResponse<T>>;},post: <T = any>(option: AxiosConfig) => {return request({ method: "post", ...option }) as Promise<IResponse<T>>;},delete: <T = any>(option: AxiosConfig) => {return request({ method: "delete", ...option }) as Promise<IResponse<T>>;},put: <T = any>(option: AxiosConfig) => {return request({ method: "put", ...option }) as Promise<IResponse<T>>;},cancelRequest: (url: string | string[]) => {return service.cancelRequest(url);},cancelAllRequest: () => {return service.cancelAllRequest();},
};

config.ts

import { AxiosResponse, InternalAxiosRequestConfig } from "./types";
import { message } from "ant-design-vue";
import qs from "qs";
import { useUserStoreWithOut } from "../pinia/user";const defaultRequestInterceptors = (config: InternalAxiosRequestConfig) => {if (config.method === "post" &&config.headers["Content-Type"] === "application/x-www-form-urlencoded") {config.data = qs.stringify(config.data);}if (config.method === "get" && config.params) {let url = config.url as string;url += "?";const keys = Object.keys(config.params);for (const key of keys) {if (config.params[key] !== void 0 && config.params[key] !== null) {url += `${key}=${encodeURIComponent(config.params[key])}&`;}}url = url.substring(0, url.length - 1);config.params = {};config.url = url;}return config;
};const defaultResponseInterceptors = (response: AxiosResponse) => {if (response?.config?.responseType === "blob") {// 如果是文件流,直接过return response;} else if (response.data.code === 0) {return response.data;} else {message.error(response?.data?.message);if (response?.data?.code === 401) {const userStore = useUserStoreWithOut();userStore.logout();}}
};export { defaultResponseInterceptors, defaultRequestInterceptors };

router填充

index.ts

import { createRouter, createWebHashHistory } from "vue-router";
import type { RouteRecordRaw } from "vue-router";
import type { App } from "vue";
import Layout from "@/views/Layout/index.vue";
const constantRouterMap = [{path: "/",name: "Login",component: () => import("@/views/Login/index.vue"),meta: {title: "登录",keepAlive: true,hideInMenu: true,},},{path: "/401",name: "error_401",meta: {hideInMenu: true,},component: () => import("@/views/ErrorPage/401.vue"),},{path: "/500",name: "error_500",meta: {hideInMenu: true,},component: () => import("@/views/ErrorPage/500.vue"),},{path: "/AAA",name: "AAA",redirect: "/AAA/BBB",component: Layout,meta: {title: "目录",},children: [{path: "BBB",name: "BBB",component: () => import("@/views/AAA/BBB/index.vue"),meta: {title: "目录1",keepAlive: true,},},{path: "CCC",component: () => import("@/views/AAA/CCC/index.vue"),name: "ChangeRecord",meta: {title: "目录2",keepAlive: true,},},{path: "DDD",component: () => import("@/views/AAA/DDD/index.vue"),name: "UploadManage",meta: {title: "目录3",keepAlive: true,},},],},
];
const router = createRouter({history: createWebHashHistory(),strict: true,routes: constantRouterMap as RouteRecordRaw[],scrollBehavior: () => ({ left: 0, top: 0 }),
}) as any;export const setupRouter = (app: App<Element>) => {app.use(router);
};export default router;

本篇结束,后面文章继续填充:Pinia + Utils公共方法

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

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

相关文章

10倍速开发开关电源:PSIM DLL集成指南与如何单步调试你的代码

文末有彩蛋哦。 去年提到要写一篇如何在利用PSIM Visual Studio进行仿真联调&#xff0c;加速实际嵌入式端C代码的开发&#xff0c;但因为懒一直没兑现。 本期简单总结下实现的方法。 特别声明&#xff1a;本文约一半以上内容有kimi/文心一言提问式生成&#xff0c;仅用于技…

Android音乐播放器的思路处理

** 1.android音乐播放播放列表中下一首上一首随机播放的思路 ** 实现 Android 音乐播放器的播放列表中的下一首、上一首和随机播放功能涉及到对音乐列表的管理以及对播放顺序的控制。以下是实现这些功能的思路&#xff1a; 下一首和上一首功能&#xff1a; 维护一个音乐列表…

【Redis】 Redis 集成到 Spring Boot上面

文章目录 &#x1f343;前言&#x1f384;Spring Boot连接redis客户端&#x1f6a9;项目的创建&#x1f6a9;配置端⼝转发&#x1f6a9;配置 redis 服务地址&#x1f6a9;更改 Redis 配置文件&#x1f6a9;使用 StringRedisTemplate 类操作 &#x1f38d;Spring Boot操作Redis客…

107.网络游戏逆向分析与漏洞攻防-装备系统数据分析-装备信息更新的处理

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 现在的代码都是依据数据包来写的&#xff0c;如果看不懂代码&#xff0c;就说明没看懂数据包…

ChatGPT3.5和ChatGPT4.0、ChatGPT4o对比

一、ChatGPT3.5、ChatGPT4.0、ChatGPT4o对比 目前ChatGPT有三个主要版本&#xff0c;分别是ChatGPT3.5、ChatGPT4.0、ChatGPT4o&#xff0c;这三个版本之间有什么差异呢&#xff1f; 对比项ChatGPT3.5ChatGPT4.0ChatGPT4o参数数量1750亿约1万亿未公开输入文本文本、图片文本、…

【el-tooltips改造】Vue实现文本溢出才显示el-tooltip,否则不显示el-tooltips

实现原理&#xff1a; 使用disabled属性控制el-tooltip的content显示与隐藏&#xff1b; 目标&#xff1a; 1行省略、多行省略、可缩放页面内的文本省略都有效。 实现方式&#xff1a; 1、自定义全局指令&#xff0c;tooltipAutoShow.js代码如下&#xff08;参考的el-table中的…

Java——数组排序

一、排序介绍 1、排序的概念 排序是将多个数据按照指定的顺序进行排列的过程。 2、排序的种类 排序可以分为两大类&#xff1a;内部排序和外部排序。 3、内部排序和外部排序 1&#xff09;内部排序 内部排序是指数据在内存中进行排序&#xff0c;适用于数据量较小的情况…

Type-C转音频(C/3.5mm接口USB2.0数据传输)带PD充电低成本解决方案

LDR6500&#xff1a;领先市场的USB-C DRP接口USB PD通信芯片 产品介绍 LDR6500&#xff0c;由乐得瑞科技精心研发&#xff0c;是一款针对USB Type-C标准中Bridge设备而优化的USB-C DRP&#xff08;Dual Role Port&#xff0c;双角色端口&#xff09;接口USB PD&#xff08;Po…

2024年安全现状报告

2024 年安全现状报告有些矛盾。尽管安全专业人员的道路困难重重&#xff0c;比如说严格的合规要求、不断升级的地缘政治紧张局势和更复杂的威胁环境&#xff0c;但整个行业还是在取得进展。 许多组织表示&#xff0c;与前几年相比&#xff0c;网络安全变得更容易管理。组织之间…

压缩视频在线压缩网站,压缩视频在线压缩工具软件

在数字化时代&#xff0c;视频成为了人们记录和分享生活的重要载体。然而&#xff0c;视频文件一般都非常大&#xff0c;这不仅占据了大量的存储空间&#xff0c;也给视频的传输和分享带来了不便。因此&#xff0c;压缩视频成为了许多人必须掌握的技能。本文将详细介绍如何压缩…

Winddow系统下关于Golang使用Cgo的配置

1.配置CGO_ENABLED为1 go env -w CGO_ENABLED1 2.安装gcc环境&#xff0c;否则出现cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in %PATH%错误 安装包&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1sgF9lijqGeP…

Python在股票交易分析中的应用:布林带与K线图的实战回测

引言 在股票交易的世界中&#xff0c;技术分析是投资者们用来预测市场动向的重要工具。布林带&#xff08;Bollinger Bands&#xff09;作为一种动态波动范围指标&#xff0c;因其直观性和实用性而广受欢迎。本文将通过Python代码&#xff0c;展示如何使用布林带结合K线图来分…

【C++PCL】点云处理对称目标函数的ICP

作者:迅卓科技 简介:本人从事过多项点云项目,并且负责的项目均已得到好评! 公众号:迅卓科技,一个可以让您可以学习点云的好地方 重点:每个模块都有参数如何调试的讲解,即调试某个参数对结果的影响是什么,大家有问题可以评论哈,如果文章有错误的地方,欢迎来指出错误的…

(第29天)【leetcode题解】222、完全二叉树的节点个数 110、平衡二叉树 257、二叉树的所有路径

目录 222、完全二叉树的节点个数题目描述思路代码 110、平衡二叉树题目描述思路代码 257、二叉树的所有路径题目描述思路代码 总结 222、完全二叉树的节点个数 题目描述 给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&#xf…

在windows下使用本地AI模型提供翻译、对话、文生图服务

文章目录 在windows下使用本地AI模型提供翻译、对话、文生图服务ollama简介下载安装配置环境变量模型安装目录服务监听地址跨域配置我的配置注意事项 开机自启 使用运行模型对话时的命令 查看本地已安装模型删除模型 查看ollama支持的模型 Docker Desktop简介下载安装配置开机自…

【C++】浅拷贝与深拷贝

在C中&#xff0c;浅拷贝&#xff08;Shallow Copy&#xff09;和深拷贝&#xff08;Deep Copy&#xff09;是两种不同的对象拷贝方式。它们之间的主要区别在于对指针成员的处理方式&#xff1a; 浅拷贝&#xff08;Shallow Copy&#xff09; 浅拷贝在C中通常是指默认的拷贝构…

STM32智能小车学习笔记(避障、循迹、跟随)

我们使用的是STM32CubeMX软件和MDK5 芯片使用的是STM32F103C8T6 完成对STM32CubeMX的初始化后开始我们的第一步点亮一个LED灯 一、点亮LED灯 点亮PC13连接的灯 打开STM32CubeMX软件&#xff0c;pc13设置为输出模式 然后按照这样配置&#xff0c;user label 设置成这个IO口代…

FJSP:烟花算法(FWA)求解柔性作业车间调度问题(FJSP),提供MATLAB代码

一、烟花算法介绍 参考文献&#xff1a; Tan, Y. and Y. Zhu. Fireworks Algorithm for Optimization. in Advances in Swarm Intelligence. 2010. Berlin, Heidelberg: Springer Berlin Heidelberg. 二、烟花算法求解FJSP 2.1FJSP模型介绍 柔性作业车间调度问题(Flexible …

git 怎么让一个文件不提交

要让一个文件不被提交到Git仓库中&#xff0c;可以使用以下几种方法&#xff1a; 方法一&#xff1a;忽略文件 1. 在项目根目录下创建一个名为 “.gitignore” 的文件。 2. 打开该文件&#xff0c;在每一行写入一个要忽略的文件或文件夹的路径&#xff0c;可以使用通配符匹配多…

Spring-core-MethodParameter

MethodParameter这个类用于方法参数的抽象&#xff0c;例如下面这个方法&#xff0c;我们就可以说test方法包含了3个MethodParameter实例&#xff0c;一个是入参aa&#xff0c;一个是入参bb&#xff0c;还有一个是String类型的返回值 public class AController {public String…