Vue 利用指令实现禁止反复发送请求的两种方法


Posted in Javascript onSeptember 15, 2019

前端做后台管控系统,在某些接口请求时间过长的场景下,需要防止用户反复发起请求。

假设某场景下用户点击查询按钮后,后端响应需要长时间才能返回数据。那么要规避用户返回点击查询按钮无外乎是让用户无法在合理时间内再次点击按钮。实现方式也有好几种:

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 利用指令实现禁止反复发送请求的两种方法,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
JavaScript实现Sleep函数的代码
Mar 04 Javascript
JS焦点图切换,上下翻转
May 12 Javascript
页面实时更新时间的JS实例代码
Dec 18 Javascript
Jquery 点击按钮自动高亮实现原理及代码
Apr 25 Javascript
jQuery is not defined 错误原因与解决方法小结
Mar 19 Javascript
Angular.JS中的this指向详解
May 17 Javascript
浅谈Vue.js中的v-on(事件处理)
Sep 05 Javascript
JavaScript实现微信红包算法及问题解决方法
Apr 26 Javascript
详解React中setState回调函数
Jun 14 Javascript
小程序实现分类页
Jul 12 Javascript
js实现简单点赞操作
Mar 17 Javascript
Node.js API详解之 string_decoder用法实例分析
Apr 29 Javascript
解决layui调用自定义方法提示未定义的问题
Sep 14 #Javascript
layui使用label标签的方法
Sep 14 #Javascript
使用layui定义一个模块并使用的例子
Sep 14 #Javascript
基于Layui自定义模块的使用方法详解
Sep 14 #Javascript
解决layui的form里的元素进行动态生成,验证失效的问题
Sep 14 #Javascript
浅谈layui使用模板引擎动态渲染元素要注意的问题
Sep 14 #Javascript
Layui Form 自定义验证的实例代码
Sep 14 #Javascript
You might like
PHP使用strstr()函数获取指定字符串后所有字符的方法
2016/01/07 PHP
ThinkPHP中session函数详解
2016/09/14 PHP
PHP中for循环与foreach的区别
2017/03/06 PHP
php把文件设置为插件的技巧方法
2020/02/03 PHP
控制打印时页眉角的代码
2007/02/08 Javascript
表单类各种类型(文本框)失去焦点效果jquery代码
2013/04/26 Javascript
json数据与字符串的相互转化示例
2013/09/18 Javascript
js获取指定的cookie的具体实现
2014/02/20 Javascript
基于jquery css3实现点击动画弹出表单源码特效
2015/08/31 Javascript
如何解决谷歌浏览器下jquery无法获取图片的尺寸
2015/09/10 Javascript
AngularJS基础 ng-non-bindable 指令详细介绍
2016/08/02 Javascript
表单input项使用label同时引用Bootstrap库导致input点击效果区增大问题
2016/10/11 Javascript
JavaScript运动框架 解决防抖动问题、悬浮对联(二)
2017/05/17 Javascript
web前端开发中常见的多列布局解决方案整理(一定要看)
2017/10/15 Javascript
vue防止花括号{{}}闪烁v-text和v-html、v-cloak用法示例
2019/03/13 Javascript
JavaScript写个贪吃蛇小游戏(超详细)
2020/03/17 Javascript
react 生命周期实例分析
2020/05/18 Javascript
[06:53]2018DOTA2国际邀请赛寻真——勇于创新的Vici Gaming
2018/08/14 DOTA
使用wxPython获取系统剪贴板中的数据的教程
2015/05/06 Python
python的pdb调试命令的命令整理及实例
2017/07/12 Python
名片管理系统python版
2018/01/11 Python
高效使用Python字典的清单
2018/04/04 Python
python画一个玫瑰和一个爱心
2020/08/18 Python
Python实现从N个数中找到最大的K个数
2020/04/02 Python
python工具快速为音视频自动生成字幕(使用说明)
2021/01/27 Python
Python 转移文件至云对象存储的方法
2021/02/07 Python
CSS3 实现侧边栏展开收起动画
2014/12/22 HTML / CSS
SheIn沙特阿拉伯:女装在线
2020/03/23 全球购物
日化店促销方案
2014/03/26 职场文书
清正廉洁演讲稿
2014/05/22 职场文书
园林技术专业求职信
2014/07/28 职场文书
六查六看六改心得体会
2014/10/14 职场文书
先进个人事迹材料范文
2014/12/30 职场文书
python实现Thrift服务端的方法
2021/04/20 Python
Django实现翻页的示例代码
2021/05/24 Python
学会Python数据可视化必须尝试这7个库
2021/06/16 Python