vue加载同样组件怎么只请求一次接口

vue项目里经常会遇到一个页面使用了两个一样的组件,这个组件会请求数据库拿一列数组。
假如不进行处理,这个页面会请求两次接口,很浪费性能,特别是比较大的数据的时候。
请问大家是怎么解决这种问题的?

一般我会把数据放入localStorage里面,这样不同页面就不会重复请求了。
但是假如一个页面引入两次这个组件,同时localStorage里面没有数据,就会请求两次,很烦哎。

阅读 11.5k
3 个回答

这个请求数据的接口用防抖节流(用哪种看需求)封装一下。可手写,也可用lodash等现有库。搜索关键词 throttledebounce

状态提升。
组件就不应该请求数据。

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);
            })
    })

}

组件中不要请求数据了呗。暴露一个参数,从上级传递过来。
甚至再判断下,如果上级没有传递,再自行请求。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题