【Vue3+TypeScript】CRM系统项目搭建之 — Axiox 网络请求封装(二)

简介: 【Vue3+TypeScript】CRM系统项目搭建之 — Axiox 网络请求封装(二)

【Vue3+TypeScript】CRM系统项目搭建之 — Axiox 网络请求封装(一):https://developer.aliyun.com/article/1556820

六、axios拦截器

axios提供了两大类拦截器:

  • 一种是请求方向的拦截(成功的、失败的)
  • 一种是响应方向的拦截(成功的,失败的)

拦截器作用:

比如:请求之前在请求头加token、强制登录

响应的时候可以进行相应的数据处理

请求拦截器

    //创建实例
    let request = axios.create({
        baseURL:'http://localhost:8080',
        timeout:5000
    });

    //配置axios拦截器
    request.interceptors.request.use(config=>{
        console.log("请求进来了...")
        console.log("请求成功方向")
        console.log(config.data.data)
        //放行请求,这一步很重要,否则报错
        return config;
    },err=>{
        console.log("请求进来了...")
        console.log("请求失败方向")
        console.log(err)
    });

    //如果没有创建实例,则使用以下方式
    //配置axios拦截器
    // axios.interceptors.request.use(config=>{
    //     console.log("请求进来了...")
    //     console.log("请求成功方向")
    //     console.log(config)
    //     //放行请求
    //     return config;
    // },err=>{
    //     console.log("请求进来了...")
    //     console.log("请求失败方向")
    //     console.log(err)
    // });

    //使用实例
    request({
        url:'get/getAll'
    }).then(res=>{
        console.log(res.data.data)
    });

响应拦截器

    //创建实例
    let request = axios.create({
        baseURL:'http://localhost:8080',
        timeout:5000
    });

    //配置axios拦截器
    request.interceptors.response.use(config=>{
        console.log("响应进来了...")
        console.log("响应成功方向")
        console.log(config.data.data)
        //放行响应
        return config;
    },err=>{
        console.log("响应进来了...")
        console.log("响应失败方向")
        console.log(err)
    });

    //使用实例
    request({
        url:'get/getAll'
    }).then(res=>{
        console.log(res.data.data)
    });


七、vue 中封装 axios

封装在request.js中

//导入axios
import axios from 'axios'

//创建axios实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 5000
})


//请求拦截器
service.interceptors.request.use(
  config => {

    if (store.getters.token) {
      config.headers['token'] = getToken()
    }
    //放行请求
    return config
  },
  error => {
    console.log(error)
    return Promise.reject(error)
  }
)


//响应拦截器
service.interceptors.response.use(
  response => {
  //返回的数据
    const res = response.data

    if (res.code !== 200) {
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 5 * 1000
      })

      // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        // to re-login
        MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
          confirmButtonText: 'Re-Login',
          cancelButtonText: 'Cancel',
          type: 'warning'
        }).then(() => {
          store.dispatch('user/resetToken').then(() => {
            location.reload()
          })
        })
      }
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
  error => {
    console.log('err' + error) // for debug
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

哪个模块需要发送请求直接引入即可,将以上实例导入

比如:此模块的所有请求接口:api下的skuInfo.js

//导入axios实例
const api_name = '/admin/product/skuInfo'

export default {

  getPageList(page, limit, searchObj) {
    return request({
      url: `${api_name}/${page}/${limit}`,
      method: 'get',
      params: searchObj
    })
  },

  save(role) {
    return request({
      url: `${api_name}/save`,
      method: 'post',
      data: role
    })
  },

  //新人专享
  isNewPerson(id, status) {
    return request({
      url: `${api_name}/isNewPerson/${id}/${status}`,
      method: 'get'
    })
  },
}

list.vue页面中使用

 //先导入
 import api from '@/api/product/skuInfo'
 api.getPageList(this.page, this.limit, this.searchObj).then(
         response => {
           debugger
           this.list = response.data.records
           this.total = response.data.total
           // 数据加载并绑定成功
           this.listLoading = false
         }
       )
     }
 api.save(this.skuInfo).then(response => {
         if (response.code) {
           this.$message({
             type: 'success',
             message: response.message
           })
           this.$router.push({ path: '/product/skuInfo/list' })
           this.saveBtnDisabled = false
         }
       })
 //新人专享
 handleNewPersonChange(index, row) {
       api.isNewPerson(row.id, row.isNewPerson).then(response => {
         this.$message({
           type: 'info',
           message: '操作成功'
         })
         this.fetchData()
       })
     }
   }

main.js中引入使用

import * as API from '@/api'
 
 Vue.prototype.$API = API


八、立足当前项目

service / index.ts

import { BASE_URL, TIME_OUT } from './config'
import HYRequest from './request'

const hyRequest = new HYRequest({
  baseURL: BASE_URL,
  timeout: TIME_OUT
})

export default hyRequest

service / config / index.ts

// 1.区分开发环境和生产环境
// export const BASE_URL = 'http://coderwhy.dev:8000'
// export const BASE_URL = 'http://codercba.prod:8000'

// 2.代码逻辑判断, 判断当前环境
// vite默认提供的环境变量
// console.log(import.meta.env.MODE)
console.log(import.meta.env.DEV) // 是否开发环境
console.log(import.meta.env.PROD) // 是否生产环境
console.log(import.meta.env.SSR) // 是否是服务器端渲染(server side render)

let BASE_URL = ''
if (import.meta.env.PROD) {
  BASE_URL = 'http://codercba.prod:8000'
} else {
  BASE_URL = 'http://coderwhy.dev:8000'
}

console.log(BASE_URL)

// 3.通过创建.env文件直接创建变量
console.log(import.meta.env.VITE_URL)

export const TIME_OUT = 10000
export { BASE_URL }

service / request / index.ts

import axios from 'axios'
import type { AxiosInstance } from 'axios'
import type { HYRequestConfig } from './type'

// 拦截器: 蒙版Loading/token/修改配置

/**
 * 两个难点:
 *  1.拦截器进行精细控制
 *    > 全局拦截器
 *    > 实例拦截器
 *    > 单次请求拦截器
 *  2.响应结果的类型处理(泛型)
 */

class HYRequest {
  instance: AxiosInstance

  // request实例 => axios的实例
  constructor(config: HYRequestConfig) {
    this.instance = axios.create(config)

    // 每个instance实例都添加拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // loading/token
        return config
      },
      (err) => {
        return err
      }
    )
    this.instance.interceptors.response.use(
      (res) => {
        return res.data
      },
      (err) => {
        return err
      }
    )

    // 针对特定的hyRequest实例添加拦截器
    this.instance.interceptors.request.use(
      config.interceptors?.requestSuccessFn,
      config.interceptors?.requestFailureFn
    )

    this.instance.interceptors.response.use(
      config.interceptors?.responseSuccessFn,
      config.interceptors?.responseFailureFn
    )
  }

  // 封装网络请求的方法
  // T => IHomeData
  request<T = any>(config: HYRequestConfig<T>) {
    // 单次请求的成功拦截处理
    if (config.interceptors?.requestSuccessFn) {
      config = config.interceptors.requestSuccessFn(config)
    }

    // 返回Promise
    return new Promise<T>((resolve, reject) => {
      this.instance
        .request<any, T>(config)
        .then((res) => {
          // 单词响应的成功拦截处理
          if (config.interceptors?.responseSuccessFn) {
            res = config.interceptors.responseSuccessFn(res)
          }
          resolve(res)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }

  get<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'GET' })
  }
  post<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'POST' })
  }
  delete<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'DELETE' })
  }
  patch<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'PATCH' })
  }
}

export default HYRequest

service / request / type.ts

import type { AxiosRequestConfig, AxiosResponse } from 'axios'

// 针对AxiosRequestConfig配置进行扩展
export interface HYInterceptors<T = AxiosResponse> {
  requestSuccessFn?: (config: AxiosRequestConfig) => AxiosRequestConfig
  requestFailureFn?: (err: any) => any
  responseSuccessFn?: (res: T) => T
  responseFailureFn?: (err: any) => any
}

export interface HYRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
  interceptors?: HYInterceptors<T>
}


目录
相关文章
|
2月前
|
JavaScript
Vue中Axios网络请求封装-企业最常用封装模式
本教程介绍如何安装并配置 Axios 实例,包含请求与响应拦截器,实现自动携带 Token、错误提示及登录状态管理,适用于 Vue 项目。
114 1
|
3月前
|
XML JSON 运维
超兔CRM基于宜搭与多系统对接的归一结构分析与设计思考
本文探讨了超兔CRM团队在使用宜搭系统对接多外部系统过程中,面临的系统耦合高、接口冗余、维护成本上升等问题,提出通过引入中间表结构与业务对象模型抽象,实现接口归一化设计。该方案有效降低系统依赖,提升数据交互标准化程度,显著提高开发与维护效率,支撑业务长期扩展。
155 2
|
1月前
|
JavaScript 前端开发 安全
Vue 3 + TypeScript 现代前端开发最佳实践(2025版指南)
每日激励:“如果没有天赋,那就一直重复”。我是蒋星熠Jaxonic,一名执着于代码宇宙的星际旅人。用Vue 3与TypeScript构建高效、可维护的前端系统,分享Composition API、状态管理、性能优化等实战经验,助力技术进阶。
Vue 3 + TypeScript 现代前端开发最佳实践(2025版指南)
|
5月前
|
自然语言处理 JavaScript 前端开发
一夜获千星!已获 1.7k+,Art Design Pro:Vue3 + Vite + TypeScript 打造的高颜值管理系统模板,这个让后端小哥直呼救命的后台系统
Art Design Pro 是一款基于 Vue 3、Vite 和 TypeScript 的高颜值后台管理系统模板,已获 1.7k+ 星标。项目专注于用户体验与视觉设计,支持主题切换、多语言、权限管理及图表展示等功能,内置常用业务组件,便于快速搭建现代化管理界面。其技术栈先进,开发体验流畅,适配多设备,满足企业级应用需求。项目地址:[GitHub](https://github.com/Daymychen/art-design-pro)。
946 11
|
4月前
|
JavaScript 安全 编译器
TypeScript 类型守卫:让你的类型系统更智能
TypeScript 类型守卫:让你的类型系统更智能
|
7月前
|
Java 数据库
jsp CRM客户管理系统(含数据库脚本以及文档)
jsp CRM客户管理系统(含数据库脚本以及文档)
163 10
|
9月前
|
JavaScript 安全 前端开发
Gzm Design:开源神器!用 Vue3、Vite4、TypeScript 革新海报设计,免费开源的海报设计器,主流技术打造,轻松高效
海报设计在各个领域都有着广泛的应用,无论是商业广告、活动宣传还是个人创意表达。今天要给大家介绍一款免费开源的海报设计器——Gzm Design,它基于最新的主流技术开发,为用户提供了丰富的功能,让海报设计变得轻松又高效。
535 64
|
9月前
|
JavaScript 数据安全/隐私保护
Vue Amazing UI 组件库(Vue3+TypeScript+Vite 等最新技术栈开发)
Vue Amazing UI 是一个基于 Vue 3、TypeScript、Vite 等最新技术栈开发构建的现代化组件库,包含丰富的 UI 组件和常用工具函数,并且持续不断维护更新中。另外,组件库全量使用 TypeScript,支持自动按需引入和 Tree Shaking 等,能够显著提升开发效率,降低开发成本。
566 5
Vue Amazing UI 组件库(Vue3+TypeScript+Vite 等最新技术栈开发)
|
9月前
|
安全 网络协议 Java
Java网络编程封装
Java网络编程封装原理旨在隐藏底层通信细节,提供简洁、安全的高层接口。通过简化开发、提高安全性和增强可维护性,封装使开发者能更高效地进行网络应用开发。常见的封装层次包括套接字层(如Socket和ServerSocket类),以及更高层次的HTTP请求封装(如RestTemplate)。示例代码展示了如何使用RestTemplate简化HTTP请求的发送与处理,确保代码清晰易维护。
|
4月前
|
JavaScript 前端开发
揭秘 TypeScript 条件类型:超越简单类型检查
揭秘 TypeScript 条件类型:超越简单类型检查

热门文章

最新文章