vue3+vite项目搭建---2.请求相关,axios+mock

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()`,
    }),
    ]
 })   
  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值