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 相关文章推荐
弹出层之1:JQuery.Boxy (一) 使用介绍
Oct 06 Javascript
Bootstrap每天必学之轮播(Carousel)插件
Apr 25 Javascript
Javascript中的迭代、归并方法详解
Jun 14 Javascript
RequireJS 依赖关系的实例(推荐)
Jan 21 Javascript
Bootstrap中data-target 到底是什么
Feb 14 Javascript
Angular中的$watch、$watchGroup、$watchCollection
Jun 25 Javascript
Node.js实现mysql连接池使用事务自动回收连接的方法示例
Feb 03 Javascript
微信小程序之判断页面滚动方向的示例代码
Aug 30 Javascript
jQuery实现的点击图片居中放大缩小功能示例
Jan 16 jQuery
JavaScript实现获取两个排序数组的中位数算法示例
Feb 26 Javascript
使用npm命令提示: 'npm' 不是内部或外部命令,也不是可运行的程序的处理方法
May 14 Javascript
vue 防止页面加载时看到花括号的解决操作
Nov 09 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
我的论坛源代码(七)
2006/10/09 PHP
解析PHP正则提取或替换img标记属性
2013/06/26 PHP
PHP小技巧之JS和CSS优化工具Minify的使用方法
2014/05/19 PHP
thinkPHP下ueditor的使用方法详解
2015/12/26 PHP
PHP 实现文件压缩解压操作的方法
2019/06/14 PHP
Kibo 用于处理键盘事件的Javascript工具库
2011/10/28 Javascript
javascript suggest效果 自动完成实现代码分享
2012/02/17 Javascript
javaScript 计算两个日期的天数相差(示例代码)
2013/12/27 Javascript
node.js中的fs.realpath方法使用说明
2014/12/16 Javascript
js实现下拉框选择要显示图片的方法
2015/02/16 Javascript
JavaScript中的parse()方法使用简介
2015/06/12 Javascript
jquery特效 点击展示与隐藏全文
2015/12/09 Javascript
Bootstrap3.0建站教程(一)之bootstrap表单元素排版
2016/06/01 Javascript
jQuery双向列表选择器DIV模拟版
2016/11/01 Javascript
详解cordova打包成webapp的方法
2017/10/18 Javascript
vue里面使用mui的弹出日期选择插件实例
2018/09/16 Javascript
mpvue 单文件页面配置详解
2018/12/02 Javascript
小程序转发探索示例
2019/02/19 Javascript
手写Vue源码之数据劫持示例详解
2021/01/04 Vue.js
[33:39]DOTA2上海特级锦标赛C组小组赛#2 LGD VS Newbee第二局
2016/02/27 DOTA
使用python实现baidu hi自动登录的代码
2013/02/10 Python
在Python中使用HTMLParser解析HTML的教程
2015/04/29 Python
python机器学习之神经网络(一)
2017/12/20 Python
python web.py开发httpserver解决跨域问题实例解析
2018/02/12 Python
Django处理Ajax发送的Get请求代码详解
2019/07/29 Python
python读写csv文件的方法
2019/08/13 Python
英国最受欢迎的手表网站:Watch Shop
2016/10/21 全球购物
男女钓鱼靴和甲板鞋:XTRATUF
2021/01/09 全球购物
主要的Ajax框架都有什么
2013/11/14 面试题
电气专业应届生求职信
2013/11/01 职场文书
《故乡》教学反思
2014/04/10 职场文书
关于诚信的活动方案
2014/08/18 职场文书
北京导游词
2015/02/12 职场文书
小区物业管理2015年度工作总结
2015/10/22 职场文书
标准版个人借条怎么写?以及什么是借条?
2019/08/28 职场文书
导游词之徐州云龙湖
2019/11/19 职场文书