vue项目里经常会遇到一个页面使用了两个一样的组件,这个组件会请求数据库拿一列数组。
假如不进行处理,这个页面会请求两次接口,很浪费性能,特别是比较大的数据的时候。
请问大家是怎么解决这种问题的?
一般我会把数据放入localStorage里面,这样不同页面就不会重复请求了。
但是假如一个页面引入两次这个组件,同时localStorage里面没有数据,就会请求两次,很烦哎。
这个请求数据的接口用防抖
或节流
(用哪种看需求)封装一下。可手写,也可用lodash
等现有库。搜索关键词 throttle
或 debounce
状态提升。
组件就不应该请求数据。
update
如果你非要这么做,也简单,如果你有做接口的统一封装,就在封装的地方加锁即可,如果没有统一封装,就劫持请求库。
加锁具体就是用url和请求参数做key,发送前标记,回来后清除,每次发送前检查标记,如果有,就说明已有相同的请求,利用evnetBus
添加监听,监听另一个请求回来时通知到的数据
const pendingMap = {}
const evnetBus = new Vue();
function request(url, data) {
return new Promise((resolve, reject) => {
// url和data做种子生成key
const key = btoa(url + JSON.stringify(data));
// 已存在相同请求,加监听,并阻止继续执行
if(pendingMap[key]){
const onCallback = res => {
eventBus.$off(key, onCallback);
const handler = res.success ? resolve : reject;
handler(res.result);
}
eventBus.$on(key, onCallback);
return
}
// 正常第一次请求
pendingMap[key] = true;
axios(url, data)
.then(res => {
pendingMap[key] = false;
const result = res.data;
// 广播事件,通知后续没有发ajax,而是等待通知的请求
eventBus.$emit(key, {success: true, result});
resolve(result);
})
.catch(err => {
pendingMap[key] = false;
eventBus.$emit(key, {success: false, result: err});
reject(err);
})
})
}
###组件中不要请求数据了呗。暴露一个参数,从上级传递过来。
甚至再判断下,如果上级没有传递,再自行请求。