【Vue工程】011-Axios

【Vue工程】011-Axios

文章目录

  • 【Vue工程】011-Axios
  • 一、概述
    • 1、简介
    • 2、官网
    • 3、訾博其他相关博客
      • 【axios】001-axios概述、特点、文档说明
      • 【axios】002-axios发起请求
      • axios封装
  • 二、基本使用
    • 1、安装
    • 2、创建一个 `token` 状态
    • 3、`axios` 封装
    • 4、使用示例
      • 设置 baseURL
      • 请求调用
      • 拦截器
  • 三、其它

一、概述

1、简介

Slogan:易用、简洁且高效的http库。

2、官网

官网:http://www.axios-js.com/zh-cn/

文档:http://www.axios-js.com/zh-cn/docs/

3、訾博其他相关博客

【axios】001-axios概述、特点、文档说明

https://blog.csdn.net/qq_29689343/article/details/109193487

【axios】002-axios发起请求

https://blog.csdn.net/qq_29689343/article/details/109193620

axios封装

https://blog.csdn.net/qq_29689343/article/details/118193238

二、基本使用

使用示例,仅作为参考!

1、安装

pnpm add axios

2、创建一个 token 状态

/src/store/token.ts

// import api from '@/api'

import { defineStore } from 'pinia';

const useTokenStore = defineStore(
  // 唯一ID
  'token',
  {
    state: () => ({
      token: localStorage.token,
      failuretime: localStorage.failuretime,
    }),
    getters: {
      isLogin: (state) => {
        let retn = false;
        if (state.token != null) {
          const unix = Date.parse(new Date().toString());
          if (unix < state.failuretime * 1000) {
            retn = true;
          }
        }
        return retn;
      },
    },
    actions: {
      login() {
        return new Promise<void>((resolve) => {
          // 模拟登录成功,写入 token 信息
          localStorage.setItem('token', '1234567890');
          localStorage.setItem(
            'failuretime',
            (
              Date.parse(new Date().toString()) / 1000 +
              24 * 60 * 60
            ).toString(),
          );
          this.token = '1234567890';
          this.failuretime =
            Date.parse(new Date().toString()) / 1000 + 24 * 60 * 60;
          resolve();
        });
      },
      // login(data) {
      //   return new Promise((resolve, reject) => {
      //     api.post('member/login', data).then((res) => {
      //       localStorage.setItem('token', '1234567890')
      //       localStorage.setItem('failuretime', Date.parse(new Date()) / 1000 + 24 * 60 * 60)
      //       this.token = '1234567890'
      //       this.failuretime = Date.parse(new Date()) / 1000 + 24 * 60 * 60
      //       resolve(res)
      //     }).catch((error) => {
      //       reject(error)
      //     })
      //   })
      // },
      logout() {
        return new Promise<void>((resolve) => {
          // 模拟退出登录,清除 token 信息
          localStorage.removeItem('token');
          localStorage.removeItem('failuretime');
          this.token = null;
          this.failuretime = null;
          resolve();
        });
      },
    },
  },
);

export default useTokenStore;

3、axios 封装

/src/api/index.ts

import axios from 'axios';

// import qs from 'qs'
import router from '@/router/index';
import useTokenStore from '@/store/token';

// 登录
async function toLogin() {
  await useTokenStore().logout();
  await router.push({
    path: '/login',
    query: {
      redirect: router.currentRoute.value.fullPath,
    },
  });
}

// axios 实例
const api = axios.create({
  baseURL:
    import.meta.env.DEV && import.meta.env.VITE_OPEN_PROXY === 'true'
      ? '/proxy/'
      : import.meta.env.VITE_APP_API_BASEURL,
  timeout: 1000 * 60,
  responseType: 'json',
});

/**
 * 请求拦截器
 */
api.interceptors.request.use((config) => {
  const tokenStore = useTokenStore();
  /**
   * 全局拦截请求发送前提交的参数
   * 以下代码为示例,在请求头里带上 token 信息
   */
  if (tokenStore.isLogin && config.headers) {
    config.headers.Token = tokenStore.token;
  }
  // 是否将 POST 请求参数进行字符串化处理
  if (config.method === 'post') {
    // config.data = qs.stringify(config.data, {
    //   arrayFormat: 'brackets',
    // })
  }
  return config;
});

/**
 * 响应拦截器
 */
api.interceptors.response.use(
  async (response) => {
    /**
     * 全局拦截请求发送后返回的数据,如果数据有报错则在这做全局的错误提示
     * 假设返回数据格式为:{ status: 1, error: '', data: '' }
     * 规则是当 status 为 1 时表示请求成功,为 0 时表示接口需要登录或者登录状态失效,需要重新登录
     * 请求出错时 error 会返回错误信息
     */
    if (response.data.status === 1) {
      if (response.data.error !== '') {
        // 这里做错误提示,如果使用了 element plus 则可以使用 Message 进行提示
        // Message.error(options)
        return Promise.reject(response.data);
      }
    } else {
      await toLogin();
    }
    return Promise.resolve(response.data);
  },
  (error) => {
    let message = error.message;
    if (message === 'Network Error') {
      message = '后端网络故障';
    } else if (message.includes('timeout')) {
      message = '接口请求超时';
    } else if (message.includes('Request failed with status code')) {
      message = `接口${message.substr(message.length - 3)}异常`;
    }
    return Promise.reject(error);
  },
);

export default api;

4、使用示例

设置 baseURL

在根目录 .env.* 文件里的 VITE_APP_API_BASEURL 这个参数就是配置 axios 的 baseURL

例如项目的真实接口请求地址为:

  • http://api.test.com/news/list
  • http://api.test.com/news/create
  • http://api.test.com/shop/info

则可设置为 VITE_APP_API_BASEURL = http://api.test.com/

请求调用

常用的 get 和 post 请求可使用以下的方法:

any 应该被替换成具体的类型!

import api from '@/api';

// GET 请求
export const getList = () => {
  return api.get<any>('/list', {
    params: {
      page: 1,
      size: 10,
    },
  });
};

// POST 请求
export const createNews = () => {
  return api.post<any>('news/create', {
    title: '新闻标题',
    content: '新闻内容',
  });
};

拦截器

/src/api/index.ts 文件里实例化了 axios 对象,并对 request 和 response 设置了拦截器,拦截器的用处就是拦截每一次的请求和响应,然后做一些全局的处理。例如接口响应报错,可以在拦截器里用统一的报错提示来展示,方便业务开发。但因为每个公司提供的接口标准不同,所以该文件拦截器部分的代码,需要开发者根据实际情况去修改调整。

代码很简单,首先初始化 axios 对象,然后 axios.interceptors.request.use()axios.interceptors.response.use() 就分别是请求和响应的拦截代码了。

参考代码里只做了简单的拦截处理,例如请求的时候会自动带上 token ,响应的时候会根据错误信息判断是登录失效还是接口报错,并做相应动作。

三、其它

更复杂(完整)的封装,可参考 vben 的封装。

https://blog.csdn.net/qq_29689343/article/details/118193238

你可能感兴趣的:(Vue.js,vue.js,javascript,前端)