針對請求模塊化封裝搭配自動化導入(簡單易用)
- 目標目錄
- 目標代碼
- 前提
- 步入正題
- src / utils / index.js
- src /api / index.js
- src /api / request.js
- src /api / service.js
- src /api / utils.js
- src /api / modules / demo.js
- 自動化配置
- vite.config.js
- eslint 校驗問題
作者GitHub:https://github.com/gitboyzcf 有興趣可關注!!!
目標目錄
目標代碼
<script setup>// 在js中直接調用useRequest() 函數就可以獲取到配置的接口const { API_DEMO_POST, API_DEMO_GET } = useRequest()// 使用非常簡單API_DEMO_GET({page: 1, pageSize: 10}).then(res => { // 請求返回結果})
</script>
接下來看下面配置👇
前提
這里用到的相關npm包
- element-plus 在這里用到了消息提示
- axios 網絡請求庫
- vueuse Vue hooks庫
- nprogress 加載進度條
- consola 好看的日志打印
以上包根據自己需求修改即可、可有可無
步入正題
src / utils / index.js
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { ElMessage } from 'element-plus'
/*** 獲取資源路徑* @param {相對路徑} relativePath* 如果要動態獲取assets的文件文件夾下的images中的圖片* relativePath 傳入 assets/images/name.png* @returns 文件所在路徑*/
const getStaticResource = (relativePath) => {return new URL(`../${relativePath}`, import.meta.url)
}/*** 消息提示* @param {彈出消息類型=》 info error warning success loading } type* @param {彈出消息文本} message* @param {彈出時間} duration* @param {彈出消息偏移} offset*/
const msg = (type, message, duration = 2000, offset = 90) => {ElMessage({message,type,duration,offset})
}/*** 模塊化方式處理 默認處理 modules文件夾下的所有js文件 內容以export default導出的文件* @param { 模塊內容集合 } moduleContext* @returns modules集合*/
const modulesHandle = (moduleContext = {}) => {if (!Object.keys(moduleContext).length) returnconst modules = {}Object.keys(moduleContext).forEach((v) => {for (let key in moduleContext[v].default) {modules[key] = moduleContext[v].default[key]}})return modules
}export { getStaticResource, modulesHandle, NProgress, msg }
src /api / index.js
import { modulesHandle } from '@/utils'const apis = modulesHandle(import.meta.glob('./modules/**/*.js', { eager: true }))
export const useRequest = () => apis
mport.meta.glob
函數從文件系統導入多個模塊,詳情請看官網 https://cn.vitejs.dev/guide/features#glob-import
src /api / request.js
import { service } from './service'
function createRequest(service) {function request(config) {// config 自定義配置// axios默認配置const configDefault = {baseURL: import.meta.env.VITE_APP_API_BASEURL, // 所有通過此配置的基礎地址 在.env文件配置timeout: 15000, // 請求超時時間responseType: 'json', // 響應類型headers: {// 請求頭配置...}}const requestConfig = Object.assign(configDefault, config)return service(requestConfig)}return request
}export const request = createRequest(service)
src /api / service.js
import axios from 'axios'
import { httpLogError, requestError, throttleToLogin } from './utils'
import { msg, NProgress } from '@/utils'
import consola from 'consola'export function createService() {const request = axios.create()request.interceptors.request.use((request) => {NProgress.start()return request},(err) => {NProgress.done()return Promise.reject(err)})request.interceptors.response.use((response) => {NProgress.done()const dataAxios = response.data// 這個狀態碼是和后端約定的const { code, data } = dataAxios// 根據 code 進行判斷if (code === undefined) {return dataAxios} else {// 目前和公司后端口頭約定是字符串,以防萬一強制轉字符串switch (`${code}`) {// code === 200 | 2 代表沒有錯誤case '200':consola.withTag(`${response.config.url}`).success()return data// code === 400001004 代表token 過期打回登錄頁case '400001004':throttleToLogin()breakcase '400':// 不是正確的 codereturn requestError(response)case '401':// 錯誤登錄return throttleToLogin()default:// 不是正確的 codereturn requestError(response)}}}, (error) => {NProgress.done()console.log(error)const status = error.response?.statusswitch (status) {// TODO 再考慮下怎么判斷是跨域問題case undefined:case null:httpLogError(error, '網路錯誤或請求跨域')breakcase 400:httpLogError(error, '請求錯誤')breakcase 401:httpLogError(error, '未授權,請登錄')breakcase 403:httpLogError(error, '拒絕訪問')breakcase 404:httpLogError(error, `請求地址出錯: ${error.response.config.url}`)breakcase 408:httpLogError(error, '請求超時')breakcase 500:httpLogError(error, '服務器內部錯誤')breakcase 501:httpLogError(error, '服務未實現')breakcase 502:httpLogError(error, '網關錯誤')breakcase 503:httpLogError(error, '服務不可用')breakcase 504:httpLogError(error, '網關超時')breakcase 505:httpLogError(error, 'HTTP版本不受支持')breakdefault:httpLogError(error, '請求錯誤')break}msg('error', error.message)return Promise.reject(error)})return request
}export const service = createService()
src /api / utils.js
import { msg as nMsg } from '@/utils'
import consola from 'consola'export const httpLogError = (error, msg) => {error.message = msgconsola.error(new Error(msg))
}export const requestError = (response) => {return new Promise((_, reject) => {const { data } = responseconst msg = `api請求出錯 ${response.config.url}:${data.message}`nMsg('error', msg)consola.error(new Error(msg))reject(data)})
}
src /api / modules / demo.js
import { request } from '@/api/request.js'
export default {API_DEMO_POST(data = {}) {return request({baseURL: '/mock/login',url: 'api/mock',method: 'post',data})},API_DEMO_GET(params = {}) {return request({url: '/demo/get',method: 'get',params})}
}
自動化配置
安裝 unplugin-auto-import/vite
插件 https://github.com/unplugin/unplugin-auto-import#readme
npm install unplugin-auto-import -D
or
pnpm install unplugin-auto-import -D
or
yarn add unplugin-auto-import -D
vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'export default defineConfig({plugins: [vue(),AutoImport({imports: ['vue','vue-router','pinia',{'@/api': ['useRequest']}],// eslintrc: {// enabled: true, // Default `false`// filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`// globalsPropValue: true // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')}})]
})
eslint 校驗問題
在vue文件中直接使用時 vscode 報紅 說未定義
- 上面
vite.config.js
中注釋部分放開,運行項目根據這個./.eslintrc-auto-import.json
相對路徑會生成該 js 文件 。 注:生成后 把enabled
屬性改為 false 以免再次生成 - .在根目錄的
eslintrc.cjs
eslint配置文件中添加下面代碼👇module.exports = {// ...'extends': [// ...'./.eslintrc-auto-import.json'] }
到這里就結束了,后續還會更新 前端 系列相關,還請持續關注!
感謝閱讀,若有錯誤可以在下方評論區留言哦!!!
推薦文章👇
Vue3-Composition API 快速上手(簡單易懂)