在 Vue 3 中使用 Axios(从入门到项目实践)
  HJwyUgQ6jyHT 2024年08月09日 40 0

Vue 3 是一个非常流行的前端框架,而 Axios 是一个基于 Promise 的 HTTP 客户端,经常用于与服务器进行交互。结合这两个工具,可以创建强大且灵活的前端应用。本博客将详细介绍如何在 Vue 3 中使用 Axios,包括基本用法、处理不同的请求类型、错误处理、拦截器、自定义实例以及在 Vue 组件中的实际应用等。为了更加贴近实际项目,本博客将重点使用 Vue 3 的 setup 语法糖。

安装 Axios

首先,我们需要安装 Axios。可以通过 npm 或 yarn 进行安装:

npm install axios
# 或者
yarn add axios

基本配置

在 Vue 3 项目中,我们通常会在 src 目录下创建一个单独的文件来配置 Axios。例如,可以创建一个 src/utils/axios.js 文件:

// src/utils/axios.js
import axios from 'axios';

const instance = axios.create({
  baseURL: 'https://', // 替换为实际的 API URL
  timeout: 10000,
});

// 请求拦截器
instance.interceptors.request.use(
  config => {
    // 在请求发送之前做一些处理,比如添加授权头
    config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;
    return config;
  },
  error => {
    // 处理请求错误
    return Promise.reject(error);
  }
);

// 响应拦截器
instance.interceptors.response.use(
  response => {
    // 对响应数据做一些处理
    return response;
  },
  error => {
    // 处理响应错误
    if (error.response && error.response.status === 401) {
      // 例如,处理未授权错误
      console.error('Unauthorized, redirecting to login...');
      // 可以添加重定向到登录页的逻辑
    }
    return Promise.reject(error);
  }
);

export default instance;

2. 在 Vue 组件中使用 Axios

发起 GET 请求

在 Vue 组件中使用 Axios 非常简单。我们可以在 setup 函数中发起请求:

<template>
  <div>
    <h1>Users</h1>
    <ul>
      <li v-for="user in users" :key="user.id">{{  }}</li>
    </ul>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue';
import axios from '../utils/axios';

export default {
  setup() {
    const users = ref([]);

    const fetchUsers = async () => {
      try {
        const response = await axios.get('/users');
        users.value = response.data;
      } catch (error) {
        console.error(error);
      }
    };

    onMounted(fetchUsers);

    return {
      users
    };
  }
};
</script>

发起 POST 请求

<template>
  <div>
    <h1>Add User</h1>
    <form @submit.prevent="addUser">
      <input v-model="" placeholder="Name" />
      <button type="submit">Add</button>
    </form>
  </div>
</template>

<script>
import { ref } from 'vue';
import axios from '../utils/axios';

export default {
  setup() {
    const newUser = ref({ name: '' });

    const addUser = async () => {
      try {
        const response = await axios.post('/users', newUser.value);
        console.log('User added:', response.data);
      } catch (error) {
        console.error(error);
      }
    };

    return {
      newUser,
      addUser
    };
  }
};
</script>

3. 错误处理

处理错误是使用 Axios 时的重要部分。我们可以在 catch 块中处理错误,并根据需要显示错误消息:

import { ref } from 'vue';
import axios from '../utils/axios';

export default {
  setup() {
    const users = ref([]);
    const errorMessage = ref('');

    const fetchUsers = async () => {
      try {
        const response = await axios.get('/users');
        users.value = response.data;
      } catch (error) {
        if (error.response) {
          // 请求已发出,服务器响应状态码不在2xx范围内
          errorMessage.value = `Error: ${error.response.data.message}`;
        } else if (error.request) {
          // 请求已发出,但没有收到响应
          errorMessage.value = 'Error: No response from server';
        } else {
          // 设置请求时发生错误
          errorMessage.value = `Error: ${error.message}`;
        }
      }
    };

    onMounted(fetchUsers);

    return {
      users,
      errorMessage
    };
  }
};

4. 使用拦截器

拦截器允许我们在请求或响应被处理之前对其进行修改。常见的用例包括添加授权头或处理全局错误。

请求拦截器

请求拦截器已经在 src/utils/axios.js 中配置,如下:

instance.interceptors.request.use(
  config => {
    // 在请求发送之前做一些处理,比如添加授权头
    config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;
    return config;
  },
  error => {
    // 处理请求错误
    return Promise.reject(error);
  }
);

响应拦截器

响应拦截器也已经在 src/utils/axios.js 中配置,如下:

instance.interceptors.response.use(
  response => {
    // 对响应数据做一些处理
    return response;
  },
  error => {
    // 处理响应错误
    if (error.response && error.response.status === 401) {
      // 例如,处理未授权错误
      console.error('Unauthorized, redirecting to login...');
      // 可以添加重定向到登录页的逻辑
    }
    return Promise.reject(error);
  }
);

5. 创建和使用自定义 Axios 实例

在某些情况下,您可能需要为不同的 API 创建多个 Axios 实例。可以轻松创建自定义实例并在组件中使用它们:

// src/utils/githubAxios.js
import axios from 'axios';

const githubAxios = axios.create({
  baseURL: 'https://',
  timeout: 10000,
});

export default githubAxios;

在组件中使用自定义实例:

<template>
  <div>
    <h1>GitHub Repos</h1>
    <ul>
      <li v-for="repo in repos" :key="repo.id">{{  }}</li>
    </ul>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue';
import githubAxios from '../utils/githubAxios';

export default {
  setup() {
    const repos = ref([]);

    const fetchRepos = async () => {
      try {
        const response = await githubAxios.get('/users/your-username/repos');
        repos.value = response.data;
      } catch (error) {
        console.error(error);
      }
    };

    onMounted(fetchRepos);

    return {
      repos
    };
  }
};
</script>

6. 使用组合式 API

Vue 3 引入了组合式 API,可以更灵活地组织组件逻辑。以下是如何在组合式 API 中使用 Axios 的示例:

<template>
  <div>
    <h1>Posts</h1>
    <ul>
      <li v-for="post in posts" :key="post.id">{{ post.title }}</li>
    </ul>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue';
import axios from '../utils/axios';

export default {
  setup() {
    const posts = ref([]);

    const fetchPosts = async () => {
      try {
        const response = await axios.get('/posts');
        posts.value = response.data;
      } catch (error) {
        console.error(error);
      }
    };

    onMounted(fetchPosts);

    return {
      posts
    };
  }
};
</script>

7. 取消请求

在某些情况下,您可能需要取消正在进行的请求,例如用户导航到其他页面时。Axios 提供了取消令牌来实现这一点:

import axios from 'axios';
const CancelToken = axios.CancelToken;
let cancel;

axios.get('/longRequest', {
  cancelToken: new CancelToken(function executor(c) {
    cancel = c;
  })
}).catch(function (thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 处理错误
  }
});

// 取消请求
cancel('Operation canceled by the user.');

在 Vue 组件中使用取消令牌:

<template>
  <div>
    <h1>Cancelable Request</h1>
    <button @click="cancelRequest">Cancel Request</button>
  </div>
</template>

<script>
import { ref, onBeforeUnmount } from 'vue';
import axios from '../utils/axios';

export default {
  setup() {
    const cancelTokenSource = ref(null);

    const fetch

Data = async () => {
      cancelTokenSource.value = axios.CancelToken.source();
      try {
        const response = await axios.get('/data', {
          cancelToken: cancelTokenSource.value.token
        });
        // 处理响应
      } catch (error) {
        if (axios.isCancel(error)) {
          console.log('Request canceled:', error.message);
        } else {
          console.error(error);
        }
      }
    };

    const cancelRequest = () => {
      if (cancelTokenSource.value) {
        cancelTokenSource.value.cancel('Operation canceled by the user.');
      }
    };

    onBeforeUnmount(() => {
      cancelRequest();
    });

    fetchData();

    return {
      cancelRequest
    };
  }
};
</script>

8. 上传和下载文件

文件上传

上传文件通常使用 FormData 对象:

<template>
  <div>
    <h1>Upload File</h1>
    <input type="file" @change="uploadFile" />
  </div>
</template>

<script>
import { ref } from 'vue';
import axios from '../utils/axios';

export default {
  setup() {
    const uploadFile = async (event) => {
      const file = event.target.files[0];
      const formData = new FormData();
      formData.append('file', file);

      try {
        const response = await axios.post('/upload', formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        });
        console.log('File uploaded:', response.data);
      } catch (error) {
        console.error(error);
      }
    };

    return {
      uploadFile
    };
  }
};
</script>

文件下载

下载文件可以通过处理 blob 数据:

<template>
  <div>
    <h1>Download File</h1>
    <button @click="downloadFile">Download</button>
  </div>
</template>

<script>
import { ref } from 'vue';
import axios from '../utils/axios';

export default {
  setup() {
    const downloadFile = async () => {
      try {
        const response = await axios.get('/download', {
          responseType: 'blob'
        });
        const url = window.URL.createObjectURL(new Blob([response.data]));
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', 'file.txt'); // 替换为实际的文件名
        document.body.appendChild(link);
        ();
        link.remove();
      } catch (error) {
        console.error(error);
      }
    };

    return {
      downloadFile
    };
  }
};
</script>

封装 Axios 实例

在实际项目中,我们通常会对 Axios 进行封装,以便在整个项目中统一管理和使用。

创建 Axios 封装

// src/api/axiosInstance.js
import axios from 'axios';

const axiosInstance = axios.create({
  baseURL: 'https://', // 替换为实际的 API URL
  timeout: 10000,
});

axiosInstance.interceptors.request.use(
  config => {
    config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

axiosInstance.interceptors.response.use(
  response => {
    return response;
  },
  error => {
    if (error.response && error.response.status === 401) {
      console.error('Unauthorized, redirecting to login...');
    }
    return Promise.reject(error);
  }
);

export default axiosInstance;

创建 API 服务

// src/api/userService.js
import axiosInstance from './axiosInstance';

export const getUsers = () => {
  return axiosInstance.get('/users');
};

export const addUser = (user) => {
  return axiosInstance.post('/users', user);
};

在组件中使用 API 服务

<template>
  <div>
    <h1>Users</h1>
    <ul>
      <li v-for="user in users" :key="user.id">{{  }}</li>
    </ul>
    <h1>Add User</h1>
    <form @submit.prevent="handleAddUser">
      <input v-model="" placeholder="Name" />
      <button type="submit">Add</button>
    </form>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue';
import { getUsers, addUser } from '../api/userService';

export default {
  setup() {
    const users = ref([]);
    const newUser = ref({ name: '' });

    const fetchUsers = async () => {
      try {
        const response = await getUsers();
        users.value = response.data;
      } catch (error) {
        console.error(error);
      }
    };

    const handleAddUser = async () => {
      try {
        const response = await addUser(newUser.value);
        console.log('User added:', response.data);
        fetchUsers(); // 刷新用户列表
      } catch (error) {
        console.error(error);
      }
    };

    onMounted(fetchUsers);

    return {
      users,
      newUser,
      handleAddUser
    };
  }
};
</script>

结论

在 Vue 3 中使用 Axios 提供了丰富的功能来处理 HTTP 请求。从基本的 GET 和 POST 请求,到复杂的拦截器、错误处理、文件上传下载,Axios 都能轻松应对。通过本文的示例和讲解,希望您能更好地在 Vue 3 项目中应用 Axios,构建高效、可靠的前端应用。封装 Axios 实例和 API 服务能使代码更加简洁和可维护,是实际项目中的最佳实践之一。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年08月09日 0

暂无评论

HJwyUgQ6jyHT