Implementación de Axios en Vue3, Vite y TypeScript para Gestión de Archivos: Carga, Descarga, Importación y Exportación

Para integrar Axios en un proyecto Vue3 con Vite y TypeScript, se configura un cliente HTTP personalizado con interceptores para manejar tokens y errores. A continuación, se define una estructura para las operaciones API y ejemplos de uso en componentes.

import axios, { InternalAxiosRequestConfig, AxiosResponse } from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useUserStore } from '@/stores/user'

const httpClient = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL,
  timeout: 30000
})

httpClient.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const userStore = useUserStore()
    if (userStore.token) {
      config.headers.set('Authorization', `Bearer ${userStore.token}`)
    }
    return config
  },
  (error) => Promise.reject(error)
)

httpClient.interceptors.response.use(
  (response: AxiosResponse) => {
    const userStore = useUserStore()
    const { code, message } = response.data

    if (response.data instanceof ArrayBuffer || response.data instanceof Blob) {
      return response
    }

    if (code === 401) {
      userStore.logout().then(() => {
        window.location.href = '/login'
      })
      return Promise.reject('Sesión inválida o expirada. Por favor, inicie sesión nuevamente.')
    } else if (code === 500) {
      ElMessage.error(message || 'Error del sistema')
    } else if (code !== 200) {
      ElMessage.warning(message)
    } else {
      return response.data
    }
  },
  (error) => {
    const { status, data } = error.response || {}
    if (status === 401) {
      ElMessageBox.alert('La sesión ha expirado. Por favor, inicie sesión de nuevo.', 'Aviso', {
        confirmButtonText: 'Aceptar',
        callback: () => {
          window.location.href = '/login'
        }
      })
    } else {
      ElMessage({
        message: data?.message || 'Error del sistema',
        type: 'error'
      })
    }
    return Promise.reject(new Error(data?.message || 'Error'))
  }
)

export default httpClient

Se crea un archivo de API, por ejemplo tasksApi.ts, con funciones para las solicitudes HTTP.

import httpClient from '@/utils/httpClient'

export function createTask(data: Record<string, unknown>) {
  return httpClient({
    url: '/tasks/create',
    method: 'post',
    data
  })
}

export function fetchTasks(params: Record<string, unknown>) {
  return httpClient({
    url: '/tasks/list',
    method: 'get',
    params
  })
}

export function downloadTasks(params: Record<string, unknown>) {
  return httpClient({
    url: '/tasks/download',
    method: 'post',
    responseType: 'blob',
    params
  })
}

export function uploadTasks(params: Record<string, unknown>, formData: FormData) {
  return httpClient({
    url: '/tasks/upload',
    method: 'post',
    headers: {
      'Content-Type': 'multipart/form-data'
    },
    params,
    data: formData
  })
}

En el componente Vue, se utilizan estas funciones para realizar operaciones. Para la descarga, se requiere el paquete file-saver, instalable mediante npm.

import { fetchTasks, uploadTasks, downloadTasks } from '@/api/tasksApi'
import { saveAs } from 'file-saver'

const loadData = async () => {
  const params = { id: 1 }
  const response = await fetchTasks(params)
  // Procesar datos de respuesta
}

const handleFileUpload = (file: File) => {
  const formData = new FormData()
  formData.append('file', file)
  const params = { id: 1 }
  uploadTasks(params, formData).then(res => {
    // Manejar éxito de carga
  })
}

const handleFileDownload = () => {
  const params = { id: 1 }
  downloadTasks(params).then(blob => {
    saveAs(blob, `datos-exportados.xlsx`)
  })
}

Etiquetas: Vue3 Vite TypeScript axios element-plus

Publicado el 6-7 20:10