创建一个基于vue3的项目并且使用 element-ui

https://www.doubao.com/thread/w476d78a62be8a4ce

网络请求封装方案

在Vue项目中,我们通常使用axios作为HTTP客户端,并对其进行封装以简化请求流程、统一错误处理和请求拦截。以下是一个完整的网络请求封装方案:

1. 安装axios

npm install axios --save

2. 创建请求配置和封装

在src目录下创建utils/request.js文件,用于封装axios:

// src/utils/request.js

import axios from 'axios';

import { ElMessage } from 'element-plus';

// 创建axios实例

const service = axios.create({

  baseURL: import.meta.env.VITE_APP_BASE_API, // 从环境变量中获取API基础路径

  timeout: 5000, // 请求超时时间

  headers: {

    'Content-Type': 'application/json;charset=utf-8',

  },

});

// 请求拦截器

service.interceptors.request.use(

  (config) => {

    // 在发送请求之前做些什么

    // 例如:添加token、设置请求头等

   

    const token = localStorage.getItem('token');

    if (token) {

      config.headers['Authorization'] = `Bearer ${token}`;

    }

   

    return config;

  },

  (error) => {

    // 对请求错误做些什么

    console.log(error);

    return Promise.reject(error);

  }

);

// 响应拦截器

service.interceptors.response.use(

  (response) => {

    // 对响应数据做些什么

    const res = response.data;

   

    // 根据业务需求判断响应状态

    if (res.code !== 200) {

      ElMessage({

        message: res.message || 'Error',

        type: 'error',

        duration: 3000,

      });

     

      // 例如:401表示未登录,跳转到登录页

      if (res.code === 401) {

        // 跳转到登录页的逻辑

        localStorage.removeItem('token');

        window.location.href = '/login';

      }

     

      return Promise.reject(new Error(res.message || 'Error'));

    } else {

      return res;

    }

  },

  (error) => {

    // 对响应错误做些什么

    console.log('err' + error); // for debug

   

    let message = error.message;

    if (error.response) {

      // 根据不同的HTTP状态码返回不同的错误信息

      const status = error.response.status;

      message = `请求错误(${status})`;

     

      switch (status) {

        case 400:

          message = '错误请求';

          break;

        case 401:

          message = '未授权,请重新登录';

          break;

        case 403:

          message = '拒绝访问';

          break;

        case 404:

          message = '请求错误,未找到该资源';

          break;

        case 500:

          message = '服务器端出错';

          break;

        default:

          message = `连接错误(${status})`;

      }

    } else if (error.message.includes('timeout')) {

      message = '请求超时';

    } else {

      message = '连接服务器失败';

    }

   

    ElMessage({

      message: message,

      type: 'error',

      duration: 3000,

    });

   

    return Promise.reject(error);

  }

);

// 封装常用的请求方法

export default {

  get(url, params = {}) {

    return service.get(url, { params });

  },

 

  post(url, data = {}) {

    return service.post(url, data);

  },

 

  put(url, data = {}) {

    return service.put(url, data);

  },

 

  delete(url, params = {}) {

    return service.delete(url, { params });

  },

};

3. 配置环境变量

在项目根目录创建.env.development和.env.production文件,分别配置开发和生产环境的API基础路径:

# .env.development

VITE_APP_BASE_API = 'http://localhost:3000/api'

# .env.production

VITE_APP_BASE_API = 'https://production-api.com/api'

4. 创建API模块

在src目录下创建api文件夹,用于组织各个模块的API请求:

// src/api/user.js

import request from '@/utils/request';

export function login(data) {

  return request.post('/user/login', data);

}

export function getUserInfo() {

  return request.get('/user/info');

}

export function logout() {

  return request.post('/user/logout');

}

5. 在组件中使用API

<!-- src/views/Login.vue -->

<template>

  <div class="login-container">

    <el-form :model="loginForm" ref="loginRef" label-width="80px">

      <el-form-item label="用户名">

        <el-input v-model="loginForm.username" placeholder="请输入用户名"></el-input>

      </el-form-item>

      <el-form-item label="密码">

        <el-input v-model="loginForm.password" type="password" placeholder="请输入密码"></el-input>

      </el-form-item>

      <el-form-item>

        <el-button type="primary" @click="handleLogin">登录</el-button>

      </el-form-item>

    </el-form>

  </div>

</template>

<script setup>

import { ref } from 'vue';

import { login } from '@/api/user';

const loginForm = ref({

  username: '',

  password: '',

});

const loginRef = ref(null);

const handleLogin = async () => {

  try {

    const { data } = await login(loginForm.value);

    localStorage.setItem('token', data.token);

    ElMessage.success('登录成功');

    // 跳转到首页

  } catch (error) {

    console.error('登录失败', error);

  }

};

</script>

封装特点和优势

1.统一错误处理:在拦截器中统一处理错误,避免在每个组件中重复编写错误处理代码

2.请求拦截:自动添加token等请求头信息

3.环境配置:区分开发环境和生产环境的API地址

4.模块化组织:按功能模块组织API请求,使代码结构更清晰

5.Promise风格:使用async/await语法,使异步请求更简洁

6.可扩展性:可以轻松添加更多功能,如请求重试、上传进度等

你可以根据实际项目需求进一步扩展这个封装,例如添加请求缓存、请求取消、上传下载等功能。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容