創(chuàng)建一個(gè)基于vue3的項(xiàng)目并且使用?element-ui

https://www.doubao.com/thread/w476d78a62be8a4ce

網(wǎng)絡(luò)請求封裝方案

在Vue項(xiàng)目中,我們通常使用axios作為HTTP客戶端,并對其進(jìn)行封裝以簡化請求流程、統(tǒng)一錯(cuò)誤處理和請求攔截。以下是一個(gè)完整的網(wǎng)絡(luò)請求封裝方案:

1. 安裝axios

npm install axios --save

2. 創(chuàng)建請求配置和封裝

在src目錄下創(chuàng)建utils/request.js文件,用于封裝axios:

// src/utils/request.js

import axios from 'axios';

import { ElMessage } from 'element-plus';

// 創(chuàng)建axios實(shí)例

const service = axios.create({

? baseURL: import.meta.env.VITE_APP_BASE_API, // 從環(huán)境變量中獲取API基礎(chǔ)路徑

? timeout: 5000, // 請求超時(shí)時(shí)間

? headers: {

? ? 'Content-Type': 'application/json;charset=utf-8',

? },

});

// 請求攔截器

service.interceptors.request.use(

? (config) => {

? ? // 在發(fā)送請求之前做些什么

? ? // 例如:添加token、設(shè)置請求頭等

? ?

? ? const token = localStorage.getItem('token');

? ? if (token) {

? ? ? config.headers['Authorization'] = `Bearer ${token}`;

? ? }

? ?

? ? return config;

? },

? (error) => {

? ? // 對請求錯(cuò)誤做些什么

? ? console.log(error);

? ? return Promise.reject(error);

? }

);

// 響應(yīng)攔截器

service.interceptors.response.use(

? (response) => {

? ? // 對響應(yīng)數(shù)據(jù)做些什么

? ? const res = response.data;

? ?

? ? // 根據(jù)業(yè)務(wù)需求判斷響應(yīng)狀態(tài)

? ? if (res.code !== 200) {

? ? ? ElMessage({

? ? ? ? message: res.message || 'Error',

? ? ? ? type: 'error',

? ? ? ? duration: 3000,

? ? ? });

? ? ?

? ? ? // 例如:401表示未登錄,跳轉(zhuǎn)到登錄頁

? ? ? if (res.code === 401) {

? ? ? ? // 跳轉(zhuǎn)到登錄頁的邏輯

? ? ? ? localStorage.removeItem('token');

? ? ? ? window.location.href = '/login';

? ? ? }

? ? ?

? ? ? return Promise.reject(new Error(res.message || 'Error'));

? ? } else {

? ? ? return res;

? ? }

? },

? (error) => {

? ? // 對響應(yīng)錯(cuò)誤做些什么

? ? console.log('err' + error); // for debug

? ?

? ? let message = error.message;

? ? if (error.response) {

? ? ? // 根據(jù)不同的HTTP狀態(tài)碼返回不同的錯(cuò)誤信息

? ? ? const status = error.response.status;

? ? ? message = `請求錯(cuò)誤(${status})`;

? ? ?

? ? ? switch (status) {

? ? ? ? case 400:

? ? ? ? ? message = '錯(cuò)誤請求';

? ? ? ? ? break;

? ? ? ? case 401:

? ? ? ? ? message = '未授權(quán),請重新登錄';

? ? ? ? ? break;

? ? ? ? case 403:

? ? ? ? ? message = '拒絕訪問';

? ? ? ? ? break;

? ? ? ? case 404:

? ? ? ? ? message = '請求錯(cuò)誤,未找到該資源';

? ? ? ? ? break;

? ? ? ? case 500:

? ? ? ? ? message = '服務(wù)器端出錯(cuò)';

? ? ? ? ? break;

? ? ? ? default:

? ? ? ? ? message = `連接錯(cuò)誤(${status})`;

? ? ? }

? ? } else if (error.message.includes('timeout')) {

? ? ? message = '請求超時(shí)';

? ? } else {

? ? ? message = '連接服務(wù)器失敗';

? ? }

? ?

? ? ElMessage({

? ? ? message: message,

? ? ? type: 'error',

? ? ? duration: 3000,

? ? });

? ?

? ? return Promise.reject(error);

? }

);

// 封裝常用的請求方法

export default {

? get(url, params = {}) {

? ? return service.get(url, { params });

? },

?

? post(url, data = {}) {

? ? return service.post(url, data);

? },

?

? put(url, data = {}) {

? ? return service.put(url, data);

? },

?

? delete(url, params = {}) {

? ? return service.delete(url, { params });

? },

};

3. 配置環(huán)境變量

在項(xiàng)目根目錄創(chuàng)建.env.development和.env.production文件,分別配置開發(fā)和生產(chǎn)環(huán)境的API基礎(chǔ)路徑:

# .env.development

VITE_APP_BASE_API = 'http://localhost:3000/api'

# .env.production

VITE_APP_BASE_API = 'https://production-api.com/api'

4. 創(chuàng)建API模塊

在src目錄下創(chuàng)建api文件夾,用于組織各個(gè)模塊的API請求:

// src/api/user.js

import request from '@/utils/request';

export function login(data) {

? return request.post('/user/login', data);

}

export function getUserInfo() {

? return request.get('/user/info');

}

export function logout() {

? return request.post('/user/logout');

}

5. 在組件中使用API

<!-- src/views/Login.vue -->

<template>

? <div class="login-container">

? ? <el-form :model="loginForm" ref="loginRef" label-width="80px">

? ? ? <el-form-item label="用戶名">

? ? ? ? <el-input v-model="loginForm.username" placeholder="請輸入用戶名"></el-input>

? ? ? </el-form-item>

? ? ? <el-form-item label="密碼">

? ? ? ? <el-input v-model="loginForm.password" type="password" placeholder="請輸入密碼"></el-input>

? ? ? </el-form-item>

? ? ? <el-form-item>

? ? ? ? <el-button type="primary" @click="handleLogin">登錄</el-button>

? ? ? </el-form-item>

? ? </el-form>

? </div>

</template>

<script setup>

import { ref } from 'vue';

import { login } from '@/api/user';

const loginForm = ref({

? username: '',

? password: '',

});

const loginRef = ref(null);

const handleLogin = async () => {

? try {

? ? const { data } = await login(loginForm.value);

? ? localStorage.setItem('token', data.token);

? ? ElMessage.success('登錄成功');

? ? // 跳轉(zhuǎn)到首頁

? } catch (error) {

? ? console.error('登錄失敗', error);

? }

};

</script>

封裝特點(diǎn)和優(yōu)勢

1.統(tǒng)一錯(cuò)誤處理:在攔截器中統(tǒng)一處理錯(cuò)誤,避免在每個(gè)組件中重復(fù)編寫錯(cuò)誤處理代碼

2.請求攔截:自動(dòng)添加token等請求頭信息

3.環(huán)境配置:區(qū)分開發(fā)環(huán)境和生產(chǎn)環(huán)境的API地址

4.模塊化組織:按功能模塊組織API請求,使代碼結(jié)構(gòu)更清晰

5.Promise風(fēng)格:使用async/await語法,使異步請求更簡潔

6.可擴(kuò)展性:可以輕松添加更多功能,如請求重試、上傳進(jìn)度等

你可以根據(jù)實(shí)際項(xiàng)目需求進(jìn)一步擴(kuò)展這個(gè)封裝,例如添加請求緩存、請求取消、上傳下載等功能。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容