面试题答案
一键面试实现步骤
- 引入必要的依赖:在Vue项目中,如果使用axios进行HTTP请求,首先要安装并引入axios。
npm install axios
- 创建自定义Hooks:使用Vue Composition API中的
onMounted
和onUnmounted
来处理组件的挂载和卸载。
import { onMounted, onUnmounted, ref } from 'vue';
import axios from 'axios';
export function useHttp() {
const response = ref(null);
const error = ref(null);
let controller;
const fetchData = async (url) => {
controller = new AbortController();
const { signal } = controller;
try {
const res = await axios.get(url, { signal });
response.value = res.data;
} catch (err) {
if (err.name === 'AbortError') {
// 请求被取消时的处理
console.log('请求已取消');
} else {
error.value = err;
}
}
};
onMounted(() => {
// 组件挂载时发起请求
fetchData('your - api - url');
});
onUnmounted(() => {
// 组件卸载时取消请求
controller && controller.abort();
});
return { response, error };
}
- 在组件中使用自定义Hooks:
<template>
<div>
<div v - if="response">
<pre>{{ response }}</pre>
</div>
<div v - if="error">{{ error }}</div>
</div>
</template>
<script setup>
import { useHttp } from './useHttp';
const { response, error } = useHttp();
</script>
处理副作用及依赖关系
- 副作用处理:在
fetchData
函数中发起HTTP请求,这是一个副作用操作。通过onMounted
和onUnmounted
生命周期钩子来控制副作用的执行和清理。onMounted
确保在组件挂载时发起请求,onUnmounted
确保在组件卸载时取消请求,避免内存泄漏。 - 依赖关系:这里的依赖关系主要是
fetchData
函数中的url
。如果url
在组件内是动态变化的,需要注意在url
变化时重新发起请求。可以通过计算属性或者watch
来监听url
的变化,并重新调用fetchData
。例如:
import { onMounted, onUnmounted, ref, watch } from 'vue';
import axios from 'axios';
export function useHttp() {
const response = ref(null);
const error = ref(null);
let controller;
const url = ref('your - api - url');
const fetchData = async () => {
controller = new AbortController();
const { signal } = controller;
try {
const res = await axios.get(url.value, { signal });
response.value = res.data;
} catch (err) {
if (err.name === 'AbortError') {
console.log('请求已取消');
} else {
error.value = err;
}
}
};
onMounted(() => {
fetchData();
});
onUnmounted(() => {
controller && controller.abort();
});
watch(url, () => {
controller && controller.abort();
fetchData();
});
return { response, error, url };
}
可能遇到的问题及解决方案
- 多次请求问题:如果在组件挂载期间,
fetchData
函数被多次调用(例如通过watch
监听数据变化触发),可能会导致多次发起请求。解决方案是在每次发起新请求前,取消之前的请求。如上述代码中watch
部分,每次url
变化时,先取消之前的请求再发起新请求。 - 兼容性问题:
AbortController
在一些旧浏览器中不支持。解决方案是使用polyfill,例如abortcontroller - polyfill
。首先安装:
npm install abortcontroller - polyfill
然后在入口文件(如main.js
)中引入:
import AbortController from 'abortcontroller - polyfill/dist/abortcontroller - polyfill';
if (!window.AbortController) {
window.AbortController = AbortController;
}
- 请求结果处理:在处理复杂业务逻辑时,可能需要对不同的HTTP状态码进行不同处理。可以在
catch
块中进一步判断err.response.status
来处理不同情况。例如:
catch (err) {
if (err.name === 'AbortError') {
console.log('请求已取消');
} else if (err.response) {
switch (err.response.status) {
case 404:
error.value = '资源未找到';
break;
case 500:
error.value = '服务器内部错误';
break;
default:
error.value = err.message;
}
} else {
error.value = err.message;
}
}