面试题答案
一键面试在created、mounted等生命周期钩子函数中进行异步数据请求的优缺点
- created钩子
- 优点:在组件实例创建完成后立即执行,此时组件尚未挂载到DOM,适合一些不需要操作DOM的异步数据请求,能尽早开始获取数据,减少用户等待时间。
- 缺点:如果请求的数据用于初始化DOM相关操作,可能因为DOM未挂载而导致问题。
- mounted钩子
- 优点:组件挂载到DOM后执行,可安全地操作DOM,若数据用于渲染或操作DOM元素,在此处请求较为合适。
- 缺点:相比created,开始请求数据时间稍晚,可能造成短暂的白屏或加载延迟。
根据业务场景选择合适的生命周期钩子来发起请求
- 数据用于初始化组件内部状态,不涉及DOM操作:优先选择
created
钩子,如获取用户基本信息用于组件内部逻辑判断。 - 数据用于渲染或操作DOM元素:使用
mounted
钩子,例如根据后台数据动态生成图表,需要操作DOM元素来绘制。
处理由于异步请求导致的数据加载不及时或多次请求的问题
- 数据加载不及时
- 加载状态管理:在组件data中定义一个loading状态,在请求开始时设为
true
,请求结束设为false
。在模板中根据loading状态显示加载动画。
<template> <div> <div v-if="loading">Loading...</div> <div v-else>{{ data }}</div> </div> </template> <script> export default { data() { return { loading: false, data: null } }, mounted() { this.loading = true; this.$axios.get('/api/data') .then(response => { this.data = response.data; this.loading = false; }) .catch(error => { this.loading = false; console.error(error); }); } } </script>
- 加载状态管理:在组件data中定义一个loading状态,在请求开始时设为
- 多次请求
- 防抖与节流:
- 防抖:在短时间内多次触发请求时,防抖函数会在最后一次触发后等待一定时间再执行请求。例如搜索框输入联想功能,可使用防抖避免频繁请求。
import { debounce } from 'lodash'; export default { data() { return { searchText: '' } }, methods: { search: debounce(function() { this.$axios.get('/api/search', { params: { q: this.searchText } }) .then(response => { // 处理响应数据 }) .catch(error => { console.error(error); }); }, 300) } }
- 节流:规定在一定时间内只能触发一次请求,适用于用户频繁滚动页面加载更多数据场景。
import { throttle } from 'lodash'; export default { data() { return { page: 1, dataList: [] } }, methods: { loadMore: throttle(function() { this.$axios.get('/api/data', { params: { page: this.page } }) .then(response => { this.dataList = [...this.dataList, ...response.data]; this.page++; }) .catch(error => { console.error(error); }); }, 500) } }
- 取消重复请求:在发送新请求前取消之前未完成的请求。例如在切换路由时,若上一个路由的请求还未完成,可取消该请求。
import axios from 'axios'; const CancelToken = axios.CancelToken; let cancel; export default { data() { return { data: null } }, mounted() { this.$axios.get('/api/data', { cancelToken: new CancelToken(c => { cancel = c; }) }) .then(response => { this.data = response.data; }) .catch(error => { if (axios.isCancel(error)) { console.log('Request canceled', error.message); } else { console.error(error); } }); }, beforeDestroy() { cancel && cancel(); } }
- 防抖与节流: