前端做后台管控系统,在某些接口请求时间过长的场景下,需要防止用户反复发起请求。
假设某场景下用户点击查询按钮后,后端响应需要长时间才能返回数据。那么要规避用户返回点击查询按钮无外乎是让用户无法在合理时间内再次点击按钮。实现方式也有好几种:
1、在按钮点击发起请求后,弹个蒙层,显示个loading,等请求数据返回了将蒙层隐藏掉。
2、在按钮点击发起请求后,将按钮禁用掉,同样等数据返回了将按钮禁用解除。
以上是比较常见的2种方案。
实现上最简单的肯定是在需要的页面种在请求前和拿到数据后,单独处理。这种方案优点仅仅是简单,但是每个需要处理的页面都要单独写一串重复的代码,哪怕利用mixin也要多不少冗余代码。
如果是利用指令的方式仅仅需要在合适的地方加上个一条v-xxxx,其他都在指令的逻辑内统一处理。
以第二种方式为例:
clickForbidden.js
let forbidClick = null; export default { bind(e) { const el = e; let timer = null; forbidClick = () => { el.disabled = true; el.classList.add('is-disabled'); timer = setTimeout(() => { el.disabled = false; el.classList.remove('is-disabled'); }, 3000); }; el.addEventListener('click', forbidClick); }, unbind() { document.removeEventListener('click', forbidClick); }, };
指令的逻辑很简单,当按钮插入到DOM节点后,添加一个监听click的事件,当按钮点击后,就将按钮禁用,并加上一个禁用样式,并在3s后将该按钮解除禁用。
再考虑请求,以axios为例:
api.js
import axios from 'axios'; export baseURL = 'xxxx'; const api = axios.create({ baseURL,<br data-filtered="filtered"> timeout: 3000, }); /* 记录当前请求是否完成 */ window.currentResq = { done: true, config: {}, }; api.interceptors.request.use(function(config) { clearTimeout(resqTimer); window.currentResq = { done: false, config, }; // 接口请求时长超过3s,则视为完成,不管请求结果成功或失败 resqTimer = setTimeout(() => { window.currentResq = { done: true, config: {}, }; }, 3000); }); api.interceptors.response.use(function(response) { const { config } = window.currentResq; const { url, method, data } = response.config; if (config.url === url && config.method === method && config.data === data) { clearTimeout(resqTimer); window.currentResq.done = true; } return response; }, function (error) { return error; }); export default api;
用一个全局的currentResq来作为请求是否完成的标志。在axios请求拦截器种,将当前请求的数据记录在currentResq中,并将done设置为false。在axios响应拦截器中,约定url,method,data3个参数一样时,就是当前currentResq中记录的请求返回数据,并将done设置为true。
同样的在指令逻辑中加入一个轮询监听currentResq的done是否完成。
clickForbidden.js
let forbidClick = null; export default { bind(e) { const el = e; let timer = null; forbidClick = () => { el.disabled = true; el.classList.add('is-disabled'); timer = setInterval(() => { if (window.currentResq.done) { clearInterval(timer); el.disabled = false; el.classList.remove('is-disabled'); } }, 500); }; el.addEventListener('click', forbidClick); }, unbind() { document.removeEventListener('click', forbidClick); }, };
这样就实现了只要在按钮上加上了v-clickForbidden
。按钮点击后就会被禁用,仅当某个请求返回数据或者3s后将按钮的禁用解除。
现在仅仅考虑按钮一次仅发送了一个请求的场景,在currentResq中也可以用一个数据来记录请求。
总结
以上所述是小给大家介绍的Vue 利用指令实现禁止反复发送请求的两种方法,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。