面试题答案
一键面试设置全局错误边界捕获网络请求错误
在Vue 3中,可以通过provide/inject
和watch
来实现全局错误捕获。
- 创建错误捕获的逻辑:
import { provide, reactive, watch } from 'vue';
const errorState = reactive({
error: null
});
const setError = (err) => {
errorState.error = err;
};
const clearError = () => {
errorState.error = null;
};
provide('errorHandler', {
setError,
clearError,
error: errorState.error
});
- 在网络请求处使用:
import { inject } from 'vue';
import axios from 'axios';
export const fetchData = async () => {
const { setError } = inject('errorHandler');
try {
const response = await axios.get('/api/data');
return response.data;
} catch (error) {
setError(error);
throw error;
}
};
- 在组件中展示错误:
<template>
<div>
<div v-if="error">{{ error.message }}</div>
<button @click="fetchData">Fetch Data</button>
</div>
</template>
<script setup>
import { inject } from 'vue';
import { fetchData } from './api';
const { error } = inject('errorHandler');
const fetchData = async () => {
await fetchData();
};
</script>
优化网络请求提升性能
避免重复请求
- 使用缓存:
const requestCache = new Map();
export const fetchDataCached = async () => {
if (requestCache.has('/api/data')) {
return requestCache.get('/api/data');
}
try {
const response = await axios.get('/api/data');
requestCache.set('/api/data', response.data);
return response.data;
} catch (error) {
throw error;
}
};
请求队列管理
- 创建请求队列:
const requestQueue = [];
const inFlightRequests = new Set();
const enqueueRequest = (config) => {
return new Promise((resolve, reject) => {
requestQueue.push({ config, resolve, reject });
processQueue();
});
};
const processQueue = () => {
if (inFlightRequests.size >= 5 || requestQueue.length === 0) return;
const { config, resolve, reject } = requestQueue.shift();
inFlightRequests.add(config.url);
axios(config)
.then(response => {
resolve(response.data);
inFlightRequests.delete(config.url);
processQueue();
})
.catch(error => {
reject(error);
inFlightRequests.delete(config.url);
processQueue();
});
};
- 使用请求队列:
export const fetchDataQueued = async () => {
return enqueueRequest({
method: 'get',
url: '/api/data'
});
};