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 相关文章推荐
Js切换功能的简单方法
Nov 23 Javascript
jQuery判断iframe中元素是否存在的方法
May 11 Javascript
js中的getAttribute方法使用示例
Aug 01 Javascript
javascript转换日期字符串为Date日期对象的方法
Feb 13 Javascript
[原创]Javascript 实现广告后加载 可加载百度谷歌联盟广告
May 11 Javascript
jQuery插件FusionWidgets实现的AngularGauge图效果示例【附demo源码】
Mar 23 jQuery
Node调用Java的示例代码
Sep 20 Javascript
iframe高度自适应及隐藏滚动条的实例详解
Sep 29 Javascript
Vue+mui实现图片的本地缓存示例代码
May 24 Javascript
微信小程序下拉菜单效果的实例代码
May 14 Javascript
layer.open提交子页面的form和layedit文本编辑内容的方法
Sep 27 Javascript
JavaScript图片旋转效果实现方法详解
Jun 28 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下通过exec获得计算机的唯一标识[CPU,网卡 MAC地址]
2011/06/09 PHP
php下通过curl抓取yahoo boss 搜索结果的实现代码
2011/06/10 PHP
PHP入门教程之PHP操作MySQL的方法分析
2016/09/11 PHP
PHP判断表达式中括号是否匹配的简单实例
2016/10/22 PHP
PHP处理bmp格式图片的方法分析
2017/07/04 PHP
用JQuery 实现AJAX加载XML并解析的脚本
2009/07/25 Javascript
Javascript 继承实现例子
2009/08/12 Javascript
IE6/7 and IE8/9/10(IE7模式)依次隐藏具有absolute或relative的父元素和子元素后再显示父元素
2011/07/31 Javascript
判断是否安装flash player及当前版本的JS代码
2013/08/08 Javascript
浅析hasOwnProperty方法的应用
2013/11/20 Javascript
动态加载iframe时get请求传递中文参数乱码解决方法
2014/05/07 Javascript
node.js中的fs.existsSync方法使用说明
2014/12/17 Javascript
浅析javascript操作 cookie对象
2014/12/26 Javascript
SpringMVC返回json数据的三种方式
2015/12/10 Javascript
JavaScript中的函数(二)
2015/12/23 Javascript
详解JavaScript节流函数中的Throttle
2016/07/16 Javascript
谈谈PHP中相对路径的问题与绝对路径的使用
2016/08/16 Javascript
Java中int与integer的区别(基本数据类型与引用数据类型)
2017/02/19 Javascript
Restify中接入Socket.io报Error:Can’t set headers的错误解决
2017/03/28 Javascript
详解react-router4 异步加载路由两种方法
2017/09/12 Javascript
vue项目打包后打开页面空白解决办法
2018/06/29 Javascript
highCharts提示框中显示当前时间的方法
2019/01/18 Javascript
浅谈Vue3.0之前你必须知道的TypeScript实战技巧
2019/09/11 Javascript
layui使用label标签的方法
2019/09/14 Javascript
[14:57]DOTA2 HEROS教学视频教你分分钟做大人-幽鬼
2014/06/13 DOTA
python图的深度优先和广度优先算法实例分析
2019/10/26 Python
HTML5使用drawImage()方法绘制图像
2014/06/23 HTML / CSS
html5 input输入实时检测以及延时优化
2018/07/18 HTML / CSS
亚马逊西班牙购物网站:amazon西班牙
2017/03/06 全球购物
乌克兰在线电子产品商店:MTA
2019/11/14 全球购物
关爱留守儿童标语
2014/06/18 职场文书
“四风”问题对照检查材料思想汇报
2014/09/16 职场文书
村干部四风问题整改措施
2014/09/30 职场文书
县委务虚会发言材料
2014/10/20 职场文书
初婚初育证明范本
2015/06/18 职场文书
抖音短视频(douyin)去水印工具的实现代码
2021/03/30 Javascript