vite+vue3
1. axios.js
安装
pnpm add axios --save
封装
axios
封装
import axios from "axios";
import Qs from "qs";
import { AxiosCanceler } from "./axiosCancel";
const config = {
baseURL: "http://localhost:3001",
timeout: 50000,
};
let axiosCanceler = new AxiosCanceler();
// 创建axios实例
var instance = axios.create();
//超时设置
instance.defaults.timeout = config.timeout;
instance.defaults.baseURL = config.baseURL;
//设置form头属性
instance.defaults.headers.post["Content-Type"] =
"application/x-www-form-urlencoded;charset=UTF-8";
//request 拦截器,统一处理请求对象
instance.interceptors.request.use(
(config) => {
// 统一请求头处理
const token = "token";
token && (config.headers.Authorization = token);
axiosCanceler.addPending(config)
return config;
},
(error) => {
return Promise.error(error);
}
);
//response 拦截器,统一处理响应对象
instance.interceptors.response.use(
(response) => {
axiosCanceler.removePending(response.config);
if (response.status === 200) {
return Promise.resolve(response.data);
} else {
return Promise.reject(response);
}
},
// 服务器状态码不是200的情况
(error) => {
if (error.response && error.response.status) {
switch (error.response.status) {
// 401: 未登录
// 未登录则跳转登录页面,并携带当前页面的路径
// 在登录成功后返回当前页面,这一步需要在登录页操作。
case 401:
console.info("跳转登录页");
break;
// 403 token过期
// 登录过期对用户进行提示
// 清除本地token和清空vuex中token对象
// 跳转登录页面
case 403:
console.info("跳转登录页登陆过期");
// 清除token
localStorage.removeItem("token");
// store.commit('loginSuccess', null);
// 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
setTimeout(() => {
console.info("跳转过期");
}, 1000);
break;
// 404请求不存在
case 404:
console.info("404");
break;
// 其他错误,直接抛出错误提示
default:
console.info("其他错误");
}
return Promise.reject(error.response);
} else {
return Promise.reject(error.message);
}
}
);
export const get = (url, params) => {
return instance({
method: "get",
url: url,
params: params
})
}
export const post = (url, data) => {
return instance({
method: "post",
url: encodeURI(url),
data: data,
headers: {
"Content-Type": "application/json"
}
})
}
export const put = (url, data) => {
return instance({
method: "put",
url: encodeURI(url),
data: data,
headers: {
"Content-Type": "application/json"
}
})
}
export const del = (url, data) => {
return instance({
method: "delete",
url: encodeURI(url),
data: data,
headers: {
"Content-Type": "application/json"
}
})
}
export const patch = (url, data) => {
return instance({
method: "patch",
url: encodeURI(url),
data: data,
headers: {
"Content-Type": "application/merge-patch+json"
}
})
}
export const upload = (url, data) => {
return instance({
method: "post",
url: encodeURI(url),
data: data,
headers: {
"Content-Type": "multipart/form-data"
}
})
}
export const postForm = (url, data) => {
return instance({
method: "post",
url: encodeURI(url),
data: Qs.stringify(data),
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
})
}
AxiosCanceler
const pendingMap = new Map();
const getPendingUrl = (config)=> {
return [config.method, config.url].join("&");
};
export class AxiosCanceler {
/**
* 添加请求
* @param config 请求配置
*/
addPending(config){
this.removePending(config);
const url = getPendingUrl(config);
const controller = new AbortController();
config.signal = controller.signal;
if (!pendingMap.has(url)) {
// 如果当前请求不在等待中,将其添加到等待中
pendingMap.set(url, controller);
}
}
/**
* 清除所有等待中的请求
*/
removeAllPending() {
pendingMap.forEach((abortController) => {
if (abortController) {
abortController.abort();
}
});
this.reset();
}
/**
* 移除请求
* @param config 请求配置
*/
removePending(config){
const url = getPendingUrl(config);
if (pendingMap.has(url)) {
// 如果当前请求在等待中,取消它并将其从等待中移除
const abortController = pendingMap.get(url);
if (abortController) {
abortController.abort(url);
}
pendingMap.delete(url);
}
}
/**
* 重置
*/
reset(){
pendingMap.clear();
}
}
router/index.js
利用路由守卫在切换页面的时候,清除所有的未完成请求
import { createRouter, createWebHashHistory } from 'vue-router'
import { AxiosCanceler } from "@/api/utils/axiosCancel"
import Layout from '@/layout/index.vue'
import Home from '@/views/home/Home.vue'
const routes = [
{
path: '/',
component: Layout,
children: [{ path: '', component: Home }],
},
]
const router = createRouter({
history: createWebHashHistory(),
routes,
})
router.beforeEach((to, from, next) => {
const axiosCanceler = new AxiosCanceler()
if (axiosCanceler) axiosCanceler.removeAllPending();
next()
});
export default router;
2. mock
安装
npm install mockjs -D
npm install vite-plugin-mock -D
目录结构
|----|mock
|----|src---mockServer.js
mock/index.js
export default [
{
url: '/api/get',
method: 'get',
response: ({ query }) => {
return {
code: 0,
data: {
name: 'vben',
},
};
},
} ]
mockServer.js
import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer';
// Import your mock .ts files one by one
// If you use vite.mock.config.ts, just import the file directly
// You can use the import.meta.glob function to import all
import routes from '../mock/index';
export function mockServer() {
createProdMockServer([...routes]);
}
vite.config.js
import { viteMockServe } from 'vite-plugin-mock';
export default defineConfig({
base: './',
plugins: [
vue(),
viteMockServe({
mockPath: './mock',
localEnabled: true,
prodEnabled: false,
injectCode: `import {mockServer} from 'mockServer';mockServer()`,
}),
]
})