[项目篇]vue3+ts 封装request请求,storage缓存,config请求信息抽离 - 第二天

简介: [项目篇]vue3+ts 封装request请求,storage缓存,config请求信息抽离 - 第二天

封装request和config请求信息抽离处理



  1. 先安装axios,毕竟请求是基于axios的。

npm: npm install axios

yarn: yarn add axios


网络异常,图片无法展示
|


  1. 在src的同级目录下,创建shims-axios.d.ts。用于做axios的ts声明


网络异常,图片无法展示
|


import { AxiosInstance, AxiosRequestConfig, AxiosPromise } from "axios"
/**
 * 自定义扩展axios模块
 * @author 何小玍。
 */
declare module "axios" {
  export interface AxiosRequestConfig {
    /**
     * @description 设置为true,则会在请求过程中显示loading动画,直到请求结束才消失
     */
    loading?: boolean
    isDialog?: boolean
  }
  export interface AxiosInstance {
    <T = any>(config: AxiosRequestConfig): Promise<T>
    request<T = any>(config: AxiosRequestConfig): Promise<T>
    get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>
    delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>
    head<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>
    post<T = any>(
      url: string,
      data?: any,
      config?: AxiosRequestConfig
    ): Promise<T>
    put<T = any>(
      url: string,
      data?: any,
      config?: AxiosRequestConfig
    ): Promise<T>
    patch<T = any>(
      url: string,
      data?: any,
      config?: AxiosRequestConfig
    ): Promise<T>
  }
}
复制代码


  1. src文件夹下,创建utils文件夹,放封装文件request.js


/**
 * @description [ axios 请求封装]
 */
// import store from "@/store";
import axios, { AxiosResponse, AxiosRequestConfig } from "axios";
// import { Message, Modal } from 'view-design' // UI组件库
import { Dialog, Toast } from "vant";
import router from "@/router";
// 根据环境不同引入不同api地址
import { config } from "@/config";
const service = axios.create({
  baseURL: config.baseApi + "/api", // url = base url + request url
  timeout: 5000,
  withCredentials: false // send cookies when cross-domain requests
  // headers: {
  //  // clear cors
  //  'Cache-Control': 'no-cache',
  //  Pragma: 'no-cache'
  // }
})
// Request interceptors
service.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    // 加载动画
    if (config.loading) {
      Toast.loading({
        message: "加载中...",
        forbidClick: true
      });
    }
    // 在此处添加请求头等,如添加 token
    // if (store.state.token) {
    // config.headers['Authorization'] = `Bearer ${store.state.token}`
    // }
    return config;
  },
  (error: any) => {
    Promise.reject(error);
  }
)
// Response interceptors
service.interceptors.response.use(
  async (response: AxiosResponse) => {
    // await new Promise(resovle => setTimeout(resovle, 3000))
    Toast.clear();
    const res = response.data;
    if (res.code !== 0) {
      // token 过期
      if (res.code === 401)
        // 警告提示窗
        return;
      if (res.code == 403) {
        Dialog.alert({
          title: "警告",
          message: res.msg
        }).then(() => {})
        return
      }
      // 若后台返回错误值,此处返回对应错误对象,下面 error 就会接收
      return Promise.reject(new Error(res.msg || "Error"))
    }
    // 注意返回值
    else return response.data
  },
  (error: any) => {
    Toast.clear();
    if (error && error.response) {
      switch (error.response.status) {
        case 400:
          error.message = "请求错误(400)"
          break
        case 401:
          error.message = "未授权,请登录(401)"
          break
        case 403:
          error.message = "拒绝访问(403)"
          break
        case 404:
          error.message = `请求地址出错: ${error.response.config.url}`
          break
        case 405:
          error.message = "请求方法未允许(405)"
          break
        case 408:
          error.message = "请求超时(408)"
          break
        case 500:
          error.message = "服务器内部错误(500)"
          break
        case 501:
          error.message = "服务未实现(501)"
          break
        case 502:
          error.message = "网络错误(502)"
          break
        case 503:
          error.message = "服务不可用(503)"
          break
        case 504:
          error.message = "网络超时(504)"
          break
        case 505:
          error.message = "HTTP版本不受支持(505)"
          break
        default:
          error.message = `连接错误: ${error.message}`
      }
    } else {
      if (error.message == "Network Error") error.message == "网络异常,请检查后重试!"
      error.message = "连接到服务器失败,请联系管理员"
    }
    Toast(error.message)
    // store.auth.clearAuth()
    // store.dispatch("clearAuth")
    return Promise.reject(error)
  }
)
export default service
复制代码


  1. src文件夹下面,创建config文件夹,放index.ts


export interface IConfig {
    env: string // 开发环境
    mock?: boolean // mock数据
    title: string // 项目title
    baseUrl?: string // 项目地址
    baseApi?: string // api请求地址
    APPID?: string // 公众号appId  一般放在服务器端
    APPSECRET?: string // 公众号appScript 一般放在服务器端
}
const dev: IConfig = {
    env: "development",
    mock: false,
    title: "开发",
    baseUrl: "http://localhost:8001", // 项目地址
    baseApi: "https://baidu.com/api", // 本地api请求地址,注意:如果你使用了代理,请设置成'/'
    APPID: "wx123456778890",
    APPSECRET: "xxx"
}
const prod: IConfig = {
    env: "production",
    mock: false,
    title: "生产",
    baseUrl: "https://www.xxx.com/", // 正式项目地址
    baseApi: "https://www.baidu.com/api", // 正式api请求地址
    APPID: "wx1234567890",
    APPSECRET: "xxx"
}
export const config: IConfig = import.meta.env.MODE == 'development' ? dev : prod
复制代码


  1. 配置.env.development.env.production文件

在根目录下,创建.env.development.env.production文件

.env.development


NODE_ENV='development'
# must start with VUE_APP_ 
VUE_APP_ENV = 'development'
OUTPUT_DIR = 'test'
复制代码


.env.production


NODE_ENV='production'
# must start with VUE_APP_
VUE_APP_ENV = 'production'
OUTPUT_DIR = 'dist'
复制代码


  1. 配置package.json文件

在scripts里面,修改成...

根据不一样的命令,走不同的config接口


"scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build",
    "prod": "cross-env NODE_ENV=dev vue-cli-service serve --mode production",
    "lint": "vue-cli-service lint --mode development"
  }
复制代码


至此 request的封装和config请求信息抽离已经完成

dev环境和prod环境也已经处理完成


封装storage文件

utils里面创建storage.ts文件, 放置storage文件


/**
 * 封装操作localstorage本地存储的方法
 */
export const storage = {
  //存储
  set(key: string, value: any) {
    localStorage.setItem(key, JSON.stringify(value))
  },
  //取出数据
  get<T>(key: string) {
    const value = localStorage.getItem(key)
    if (value && value != "undefined" && value != "null") {
      return <T>JSON.parse(value)
    }
  },
  // 删除数据
  remove(key: string) {
    localStorage.removeItem(key)
  }
};
/**
 * 封装操作sessionStorage本地存储的方法
 */
export const sessionStorage = {
  //存储
  set(key: string, value: any) {
    window.sessionStorage.setItem(key, JSON.stringify(value))
  },
  //取出数据
  get<T>(key: string) {
    const value = window.sessionStorage.getItem(key)
    if (value && value != "undefined" && value != "null") {
      return JSON.parse(value)
    }
    return null
  },
  // 删除数据
  remove(key: string) {
    window.sessionStorage.removeItem(key)
  }
}


相关文章
|
3月前
|
存储 JavaScript
vue页面跳转取消上一个页面请求
本文介绍了在Vue中如何取消上一个页面的请求,以避免页面跳转时请求未完成导致的数据错误。核心方法是使用axios的请求拦截器设置请求的取消令牌(cancelToken),并在vuex中存储这些取消令牌的引用。当进行路由跳转时,通过路由守卫清除这些请求,达到取消上一个页面请求的目的。
192 2
|
2月前
|
缓存 JavaScript 搜索推荐
vue中的一个内置组件Keep-Alive的作用及使用方法介绍——缓存不活动的组件实例
vue中的一个内置组件Keep-Alive的作用及使用方法介绍——缓存不活动的组件实例
142 1
|
3月前
vite.config.js中vite.defineConfig is not defined以及创建最新版本的vite项目
本文讨论了在配置Vite项目时遇到的`vite.defineConfig is not defined`错误,这通常是由于缺少必要的导入语句导致的。文章还涉及了如何创建最新版本的Vite项目以及如何处理`configEnv is not defined`的问题。
219 3
vite.config.js中vite.defineConfig is not defined以及创建最新版本的vite项目
|
2月前
|
存储 缓存 JavaScript
Vue3实现页面缓存
【10月更文挑战第9天】
133 1
|
2月前
|
缓存 JavaScript 前端开发
Vue 3的事件监听缓存如何优化性能?
【10月更文挑战第5天】随着前端应用复杂度的增加,性能优化变得至关重要。Vue 3 通过引入事件监听缓存等新特性提升了应用性能。本文通过具体示例介绍这一特性,解释其工作原理及如何利用它优化性能。与 Vue 2 相比,Vue 3 可在首次渲染时注册事件监听器并在后续渲染时重用,避免重复注册导致的资源浪费和潜在内存泄漏问题。通过使用 `watchEffect` 或 `watch` 监听状态变化并更新监听器,进一步提升应用性能。事件监听缓存有助于减少浏览器负担,特别在大型应用中效果显著,使应用更加流畅和响应迅速。
101 1
|
3月前
|
JavaScript
Vue3基础(19)___vite.config.js中配置路径别名
本文介绍了如何在Vue 3的Vite配置文件`vite.config.js`中设置路径别名,以及如何在页面中使用这些别名导入模块。
146 0
Vue3基础(19)___vite.config.js中配置路径别名
|
2月前
|
前端开发 JavaScript
vite vue3 config配置
【10月更文挑战第5天】
100 0
|
4月前
|
缓存 JavaScript
Vue学习之--------编程式路由导航、缓存路由组件、新的钩子函数(4)(2022/9/5)
这篇文章介绍了Vue中编程式路由导航的方法,包括使用`$router.push`、`$router.replace`、`$router.forward`、`$router.back`和`$router.go`进行路由跳转和历史记录操作,以及如何利用`<keep-alive>`组件缓存路由组件,和Vue Router新增的两个生命周期钩子`activated`和`deactivated`的用法及其在项目中的应用和测试结果。
Vue学习之--------编程式路由导航、缓存路由组件、新的钩子函数(4)(2022/9/5)
|
3月前
|
缓存 JavaScript
vue使用keep-alive实现页面前进刷新,后退缓存,完美运行无bug
vue使用keep-alive实现页面前进刷新,后退缓存,完美运行无bug
599 1
|
4月前
|
JavaScript API
Vue3 运行可以,build 打包发布报错,app.config.globalProperties 用法坑
Vue3 运行可以,build 打包发布报错,app.config.globalProperties 用法坑
110 2