BongoCat桌面宠物完整指南:从零开始打造你的专属数字伙伴
2026/1/12 9:13:41
背景问题:
需要统一管理 HTTP 请求。
方案思考:
封装 Axios 并添加请求拦截器。
具体实现:
// utils/request.jsimportaxiosfrom'axios'import{ElMessage,ElNotification}from'element-plus'import{useUserStore}from'@/stores/modules/user'// 创建 axios 实例constservice=axios.create({baseURL:import.meta.env.VITE_APP_BASE_API||'/api',timeout:15000,headers:{'Content-Type':'application/json;charset=UTF-8'}})// 请求拦截器service.interceptors.request.use(config=>{// 添加认证 tokenconsttoken=localStorage.getItem('access_token')if(token){config.headers['Authorization']=`Bearer${token}`}// 添加请求时间戳,防止缓存if(config.method==='get'){config.params={...config.params,_t:Date.now()}}console.log('发送请求:',config)returnconfig},error=>{console.error('请求错误:',error)returnPromise.reject(error)})// 响应拦截器service.interceptors.response.use(response=>{constres=response.data// 根据后端约定的状态码处理if(res.code&&res.code!==200){ElMessage.error(res.message||'请求失败')// 401: 未登录或登录已过期if(res.code===401){// 清除用户信息constuserStore=useUserStore()userStore.clearUser()// 跳转到登录页window.location.href='/login'}returnPromise.reject(newError(res.message||'Error'))}else{returnres}},error=>{console.error('响应错误:',error)letmessage='请求失败'if(error.response){// 服务器返回错误状态码conststatus=error.response.statusswitch(status){case400:message='请求参数错误'breakcase401:message='未授权,请重新登录'// 清除用户信息并跳转登录页constuserStore=useUserStore()userStore.clearUser()window.location.href='/login'breakcase403:message='拒绝访问'breakcase404:message='请求资源不存在'breakcase500:message='服务器内部错误'breakdefault:message=`连接错误${status}`}}elseif(error.request){// 请求已发出但没有收到响应message='网络连接异常'}else{// 其他错误message=error.message}ElMessage.error(message)returnPromise.reject(error)})exportdefaultserviceAPI 接口封装示例:
// api/user.jsimportrequestfrom'@/utils/request'// 获取用户列表exportfunctiongetUserList(params){returnrequest({url:'/users',method:'get',params})}// 获取用户详情exportfunctiongetUserById(id){returnrequest({url:`/users/${id}`,method:'get'})}// 创建用户exportfunctioncreateUser(data){returnrequest({url:'/users',method:'post',data})}// 更新用户exportfunctionupdateUser(id,data){returnrequest({url:`/users/${id}`,method:'put',data})}// 删除用户exportfunctiondeleteUser(id){returnrequest({url:`/users/${id}`,method:'delete'})}// 批量删除用户exportfunctionbatchDeleteUser(ids){returnrequest({url:'/users/batch-delete',method:'post',data:{ids}})}在组件中使用请求示例:
<template> <div class="user-list"> <el-table :data="userList" v-loading="loading"> <el-table-column prop="id" label="ID" width="100" /> <el-table-column prop="username" label="用户名" /> <el-table-column prop="email" label="邮箱" /> <el-table-column prop="createdAt" label="创建时间" /> <el-table-column label="操作" width="200"> <template #default="{ row }"> <el-button size="small" @click="editUser(row)">编辑</el-button> <el-button size="small" type="danger" @click="deleteUser(row.id)">删除</el-button> </template> </el-table-column> </el-table> <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :total="total" :page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </div> </template> <script setup> import { ref, onMounted } from 'vue' import { getUserList, deleteUser } from '@/api/user' const userList = ref([]) const loading = ref(false) const currentPage = ref(1) const pageSize = ref(10) const total = ref(0) // 获取用户列表 const fetchUserList = async () => { loading.value = true try { const response = await getUserList({ page: currentPage.value, size: pageSize.value }) userList.value = response.data.list total.value = response.data.total } catch (error) { console.error('获取用户列表失败:', error) } finally { loading.value = false } } // 删除用户 const deleteUserHandler = async (id) => { try { await deleteUser(id) ElMessage.success('删除成功') fetchUserList() // 重新获取列表 } catch (error) { console.error('删除用户失败:', error) } } // 分页处理 const handleSizeChange = (size) => { pageSize.value = size fetchUserList() } const handleCurrentChange = (page) => { currentPage.value = page fetchUserList() } onMounted(() => { fetchUserList() }) </script>