vue项目中axios封装(数据请求封装)

一、定义utils(工具类)目录,并创建两个文件,request.js与http.js

request.js

用于创建axios,并在请求/响应拦截时对需要传递的数据进行处理。

// 引入 axios
import axios from "axios"; // 使用前要先安装依赖:npm install axios

//引入 element-ui 信息
import { Message } from "element-ui";
import router from "@/router";

// 创建axios实例
const service = axios.create({
  // 这里可以放一下公用属性等。
  //baseURL: process.env.VUE_APP_BASE_API, // 使用环境变量
  baseURL: "https://xxxx", // 用于配置请求接口公用部分,请求时会自动拼接在你定义的url前面。
  withCredentials: false, // 跨域请求时是否需要访问凭证
  timeout: 5000, // 请求超时时间
  headers: {
    // 可以放一下公用的请求头信息
    Accept: "application/json",
    "Content-Type": "application/json",
  },
});

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    // 在这里可以进行请求加密等操作,比如添加 token、cookie,修改数据传输格式等。
    // 设置请求头
    config.headers.Accept = "application/json";
    config.headers["Content-Type"] = "application/json";
    // 获取 token 并设置 Authorization 头部
    let token =
      window.localStorage.getItem("token") ||
      window.sessionStorage.getItem("token");
    if (token) {
      config.headers["Authorization"] = "Bearer " + token;
    }
    // 可根据需要添加其他自定义头部
    // config.headers["custom-header"] = "xxxx";
    return config;
  },
  (error) => {
    console.log(error);
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response) => {
    // 对响应数据做处理
    return response;
  },
  (error) => {
    // 请求失败进行的操作
    if (error.response && error.response.status) {
      switch (error.response.status) {
        case 401:
          Message.warning("尚未登录,请登录!");
          router.push("/login");
          break;
        case 403:
          Message.error("权限不足!");
          break;
        case 404:
          Message.error("请求资源不存在!");
          break;
        case 500:
          Message.error("服务器错误!");
          break;
        default:
          Message.error(`请求错误: ${error.response.status} - ${error.response.data.message}`);
      }
    } else {
      Message.error("网络错误或请求超时!");
    }
    return Promise.reject(error);
  }
);

export default service;

http.js

import service from "./request";

const HttpMethod = {
  GET: "GET",
  POST: "POST",
  PUT: "PUT",
  DELETE: "DELETE",
};

const defaultHeaders = {
  "Content-Type": "application/json",
};

const createConfig = (method, url, data = {}, headers = {}, config = {}) => ({
  method,
  url,
  ...(method === HttpMethod.GET || method === HttpMethod.DELETE
    ? { params: data }
    : { data }),
  headers: { ...defaultHeaders, ...headers },
  ...config, // 支持额外的配置选项
});

const handleResponse = async (requestPromise, method, url) => {
  try {
    const response = await requestPromise;
    return response.data;
  } catch (error) {
    console.error(
      `Error occurred while making ${method} request to ${url}:`,
      error.response ? 
        `${error.response.status} - ${error.response.data.message}` : 
        error.message
    );
    throw error; // 重新抛出错误,以便调用者可以处理
  }
};

const http = {
  request(method, url, data = {}, headers = {}, config = {}) {
    const requestConfig = createConfig(method, url, data, headers, config);
    return handleResponse(service(requestConfig), method, url); // 传入报错时可定位到method 和 url
  },
  get(url, params = {}, headers = {}, config = {}) {
    return this.request(HttpMethod.GET, url, params, headers, config);
  },
  post(url, data = {}, headers = {}, config = {}) {
    return this.request(HttpMethod.POST, url, data, headers, config);
  },
  put(url, data = {}, headers = {}, config = {}) {
    return this.request(HttpMethod.PUT, url, data, headers, config);
  },
  delete(url, params = {}, headers = {}, config = {}) {
    return this.request(HttpMethod.DELETE, url, params, headers, config);
  },
};

export default http;

二、定义存放接口目录(api),假设首页需请求接口,添加home.js

home.js

import http from "@/utils/http";

export function fetchList(params = {}, headers = {}, config = {}) {
  return http.get("/api/getList", params, headers, config);
}

export function createList(data = {}, headers = {}, config = {}) {
  return http.post("/api/postList", data, headers, config);
}

export function updateList(data = {}, headers = {}, config = {}) {
  return http.put("/api/putList", data, headers, config);
}

export function removeList(params = {}, headers = {}, config = {}) {
  return http.delete("/api/deleteList", params, headers, config);
}

三、home.vue文件中使用。

<template>
  <div>
    <button @click="getList">获取列表</button>
    <ul>
      <li v-for="item in list" :key="item.id">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script>
import { fetchList, createList, updateList, removeList } from '@/utils/api';

export default {
  data() {
    return {
      list: []
    };
  },
  methods: {
    async getList() {
      try {
        const params = { page: 1, size: 10 }; // 示例参数
        const response = await fetchList(params);
        this.list = response.data;
      } catch (error) {
        console.error("Error fetching list:", error);
      }
    },
    
    async addItem(newItem) {
      try {
        const response = await createList(newItem);
        this.list.push(response.data);
      } catch (error) {
        console.error("Error creating list item:", error);
      }
    },

    async updateItem(updatedItem) {
      try {
        const response = await updateList(updatedItem);
        const index = this.list.findIndex(item => item.id === updatedItem.id);
        if (index !== -1) {
          this.list.splice(index, 1, response.data);
        }
      } catch (error) {
        console.error("Error updating list item:", error);
      }
    },

    async deleteItem(id) {
      try {
        await removeList({ id });
        this.list = this.list.filter(item => item.id !== id);
      } catch (error) {
        console.error("Error deleting list item:", error);
      }
    }
  }
};
</script>

<style scoped>
/* 样式 */
</style>

posted @ 2024-06-13 11:26  苏沐~  阅读(374)  评论(0编辑  收藏  举报