chaihongjun.me

vue3项目中极简axios封装与应用

axios在前端项目中作为一个网络请求库,它可以运行在浏览器和node.js环境中,因此非常的流行。vue3项目中极简axios封装与应用,在日常开发的简单应用中即可拿来主义直接使用。

首先是在项目跟了目录中安装axios和element-plus组件库

npm i axios element-plus

然后在src目录创建/request/index.js文件:

import axios from 'axios'
import { ElMessage } from 'element-plus'

// 创建 axios 实例
const service = axios.create({
  baseURL: 'https://jsonplaceholder.typicode.com', // 根据实际情况修改基础 URL
  timeout: 3000, // 请求超时时间
})

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    // 在发送请求之前做些什么,例如添加token
    // const token = localStorage.getItem('token');
    // if (token) {
    //   config.headers.Authorization = `Bearer ${token}`;
    // }
    return config
  },
  (error) => {
    // 对请求错误做些什么
    console.error('Request Error:', error)
    return Promise.reject(error)
  },
)

// 响应拦截器
service.interceptors.response.use(
  (response) => {
    // 对响应数据做点什么
    return response.data
  },
  (error) => {
    // 对响应错误做点什么
    let errorMessage = '请求失败,请稍后再试'
    if (error.response) {
      switch (error.response.status) {
        case 400:
          errorMessage = '请求错误(400)'
          break
        case 401:
          errorMessage = '未授权,请重新登录(401)'
          break
        case 403:
          errorMessage = '拒绝访问(403)'
          break
        case 404:
          errorMessage = '请求出错(404)'
          break
        case 408:
          errorMessage = '请求超时(408)'
          break
        case 500:
          errorMessage = '服务器错误(500)'
          break
        case 501:
          errorMessage = '服务未实现(501)'
          break
        case 502:
          errorMessage = '网络错误(502)'
          break
        case 503:
          errorMessage = '服务不可用(503)'
          break
        case 504:
          errorMessage = '网络超时(504)'
          break
        case 505:
          errorMessage = 'HTTP版本不受支持(505)'
          break
        default:
          errorMessage = `连接出错(${error.response.status})`
      }
    } else if (error.request) {
      errorMessage = '连接到服务器失败'
    } else {
      errorMessage = error.message
    }
    ElMessage.error(errorMessage)
    return Promise.reject(error)
  },
)

export default service

接着写API调用,在src目录创建/api/index.js文件:

import service from '@/request/index.js'

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

export const getUser = (id) => {
  return service.get(`/users/${id}`)
}

export const getPosts = () => {
  return service.get('/posts')
}

export const getPost = (id) => {
  return service.get(`/posts/${id}`)
}

上面的代码就完成了API请求的封装。

在实际项目应用中,可能会把API请求的数据保存到store中:

// src/stores/counter.js
import { ref } from 'vue'
import { defineStore } from 'pinia'
import { getUser, getUsers } from '@/api/index.js' //导入API请求

export const useCounterStore = defineStore('counter', () => {
  // State
  const users = ref([]) //全部用户数据
  const user = ref(null) //单个用户数据
  // Actions 用于改变State
  // 获取全部用户数据
  const fetchUsers = async () => {
    try {
      users.value = await getUsers()
      console.log('Fetched users:', users.value) // 添加日志输出
    } catch (error) {
      console.error('Failed to fetch users:', error)
    }
  }
  // 获取单个用户数据
  const fetchUser = async (id) => {
    try {
      user.value = await getUser(id)
    } catch (error) {
      console.error('Failed to fetch user:', error)
    }
  }

  return {  //作为Store的属性,需要将State 和 Actions 暴露出去提供组件访问
    users,
    user,
    fetchUsers,
    fetchUser,
  }
})

在组件内:

<template>
  <div class="list">
    <h3>User List</h3>
    <ul>
      <li v-for="user in users" :key="user.id" @click="selectUser(user.id)">
        {{ user.name }}
      </li>
    </ul>
    <div v-if="selectedUser">
      <h2>User Details</h2>
      <p>ID: {{ selectedUser.id }}</p>
      <p>Name: {{ selectedUser.name }}</p>
      <p>Email: {{ selectedUser.email }}</p>
    </div>
  </div>
</template>
<script setup>
import { ref, onMounted, toRefs } from 'vue'
import { useCounterStore } from '@/stores/counter.js' //引入Store实例
const counterStore = useCounterStore() //获得store实例,这个实例包含了state和actions
const { users, user } = toRefs(counterStore) //解构会造成丢失响应式,使用toRefs保持属性响应式

const selectedUser = ref(null)

//选择某一个用户数据
async function selectUser (id) {
  await counterStore.fetchUser(id)
  selectedUser.value = user.value
}
onMounted(async () => {
  await counterStore.fetchUsers() //组件挂载加载数据
});
</script>

组件引入Store实例之后,可以在组件内使用相应的State和Actions。

知识共享许可协议本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。作者:柴宏俊»