В современной веб-разработке взаимодействие с REST API является ключевым аспектом большинства приложений. В этом уроке мы детально рассмотрим работу с HTTP-запросами в Vue.js используя библиотеку Axios
Содержание
Установка и настройка Axios
npm install axios
# или
yarn add axios
Базовая настройка в проекте:
// src/plugins/axios.js
import axios from 'axios'
const axiosInstance = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000,
headers: {
'Content-Type': 'application/json'
}
})
export default axiosInstance
Использование в компоненте:
// src/components/UserList.vue
import axios from '@/plugins/axios'
export default {
data() {
return {
users: [],
loading: false,
error: null
}
},
methods: {
async fetchUsers() {
this.loading = true
try {
const response = await axios.get('/users')
this.users = response.data
} catch (error) {
this.error = error.message
} finally {
this.loading = false
}
}
}
}
Обработка ошибок
Глобальная обработка ошибок:
// src/plugins/axios.js
axiosInstance.interceptors.response.use(
response => response,
error => {
if (error.response) {
switch (error.response.status) {
case 401:
// Перенаправление на страницу логина
router.push('/login')
break
case 404:
// Обработка "не найдено"
break
case 500:
// Обработка серверных ошибок
break
}
}
return Promise.reject(error)
}
)
Локальная обработка ошибок:
async createUser(userData) {
try {
const response = await axios.post('/users', userData)
this.$notify({
type: 'success',
message: 'Пользователь успешно создан'
})
return response.data
} catch (error) {
this.$notify({
type: 'error',
message: error.response?.data?.message || 'Произошла ошибка'
})
throw error
}
}
Interceptors (Перехватчики)
// Перехватчик запросов
axios.interceptors.request.use(
config => {
// Добавление токена авторизации
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
error => Promise.reject(error)
)
// Перехватчик ответов
axios.interceptors.response.use(
response => {
// Обработка успешного ответа
return response
},
error => {
// Обработка ошибок
return Promise.reject(error)
}
)
Кэширование запросов
// src/utils/cacheService.js
const cache = new Map()
export const cacheService = {
set(key, data, ttl = 60000) {
cache.set(key, {
data,
timestamp: Date.now(),
ttl
})
},
get(key) {
const cached = cache.get(key)
if (!cached) return null
if (Date.now() - cached.timestamp > cached.ttl) {
cache.delete(key)
return null
}
return cached.data
}
}
// Использование кэширования
async function fetchDataWithCache(url) {
const cachedData = cacheService.get(url)
if (cachedData) return cachedData
const response = await axios.get(url)
cacheService.set(url, response.data)
return response.data
}
Отмена запросов
export default {
data() {
return {
abortController: null
}
},
methods: {
async fetchData() {
// Отмена предыдущего запроса
if (this.abortController) {
this.abortController.abort()
}
// Создание нового контроллера
this.abortController = new AbortController()
try {
const response = await axios.get('/api/data', {
signal: this.abortController.signal
})
return response.data
} catch (error) {
if (axios.isCancel(error)) {
console.log('Запрос отменен')
} else {
console.error('Ошибка:', error)
}
}
}
},
beforeUnmount() {
if (this.abortController) {
this.abortController.abort()
}
}
}
Загрузка файлов
async uploadFile(file) {
const formData = new FormData()
formData.append('file', file)
try {
const response = await axios.post('/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
this.uploadProgress = percentCompleted
}
})
return response.data
} catch (error) {
console.error('Ошибка загрузки:', error)
throw error
}
}
Пример компонента загрузки файлов:
<template>
<div class="upload-component">
<input type="file" @change="handleFileSelect">
<div v-if="uploading" class="progress">
Загрузка: {{ progress }}%
<div class="progress-bar" :style="{ width: `${progress}%` }"></div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
uploading: false,
progress: 0
}
},
methods: {
async handleFileSelect(event) {
const file = event.target.files[0]
if (!file) return
this.uploading = true
this.progress = 0
try {
await this.uploadFile(file)
this.$emit('upload-success')
} catch (error) {
this.$emit('upload-error', error)
} finally {
this.uploading = false
}
}
}
}
</script>
Практические советы
- Всегда используйте try/catch для обработки ошибок
- Реализуйте механизм повторных попыток для важных запросов
- Используйте кэширование для оптимизации производительности
- Не забывайте об отмене запросов при размонтировании компонентов
- Реализуйте индикаторы загрузки для улучшения UX
Это базовое руководство по работе с REST API в Vue.js. Каждый раздел можно расширить дополнительными примерами и случаями использования в зависимости от потребностей проекта
Еще больше уроков для изучения Vue