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 相关文章推荐
服务器安全设置的几个注册表设置
Jul 28 Javascript
node在两个div之间移动,用ztree实现
Mar 06 Javascript
Ext JS 4实现带week(星期)的日期选择控件(实战二)
Aug 21 Javascript
实例讲解jQuery中对事件的命名空间的运用
May 24 Javascript
jQuery解析与处理服务器端返回xml格式数据的方法详解
Jul 04 Javascript
jQuery调用Webservice传递json数组的方法
Aug 06 Javascript
js 自带的sort() 方法全面了解
Aug 16 Javascript
利用jquery去掉时光轴头尾部线条的方法实例
Jun 16 jQuery
vue中使用refs定位dom出现undefined的解决方法
Dec 21 Javascript
js+css实现红包雨效果
Jul 12 Javascript
彻底揭秘keep-alive原理(小结)
May 05 Javascript
利用js实现简单开关灯代码
Nov 23 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
全国FM电台频率大全 - 23 四川省
2020/03/11 无线电
WAR3重制版DOTA 5V5初体验
2020/04/09 DOTA
增加反向链接的101个方法 站长推荐
2007/01/31 PHP
PHP7.0版本备注
2015/07/23 PHP
WIFI万能钥匙密码查询接口实例
2015/09/28 PHP
jquery修改属性值实例代码(设置属性值)
2014/01/06 Javascript
jQuery实现带渐显效果的人物多级关系图代码
2015/10/16 Javascript
AngularJS 文件上传控件 ng-file-upload详解
2017/01/13 Javascript
bootstrap 设置checkbox部分选中效果
2017/04/20 Javascript
JS实现获取图片大小和预览的方法完整实例【兼容IE和其它浏览器】
2017/04/24 Javascript
JavaScript订单操作小程序完整版
2017/06/23 Javascript
vuejs使用axios异步访问时用get和post的实例讲解
2018/08/09 Javascript
JavaScript简单实现动态改变HTML内容的方法示例
2018/12/25 Javascript
微信小程序实现简单表格
2019/02/14 Javascript
js实现鼠标拖拽缩放div实例代码
2019/03/25 Javascript
详解keep-alive + vuex 让缓存的页面灵活起来
2019/04/19 Javascript
layer.msg()去掉默认时间,实现手动关闭的方法
2019/09/12 Javascript
详解Vue3 Composition API中的提取和重用逻辑
2020/04/29 Javascript
Python自动连接ssh的方法
2015/03/07 Python
windows下ipython的安装与使用详解
2016/10/20 Python
Python实现的手机号归属地相关信息查询功能示例
2017/06/08 Python
用 Python 爬了爬自己的微信朋友(实例讲解)
2017/08/25 Python
python实现图书管理系统
2018/03/12 Python
浅析Python装饰器以及装饰器模式
2018/05/28 Python
Python3爬虫爬取百姓网列表并保存为json功能示例【基于request、lxml和json模块】
2018/12/05 Python
python批量创建指定名称的文件夹
2019/03/21 Python
Python爬虫动态ip代理防止被封的方法
2019/07/07 Python
python 实现矩阵填充0的例子
2019/11/29 Python
html5的canvas实现3d雪花飘舞效果
2013/12/27 HTML / CSS
方太官方网上商城:销售方太抽油烟机、燃气灶、消毒柜等
2017/01/17 全球购物
以设计师精品品质提供快速时尚:PopJulia
2018/01/09 全球购物
广告学毕业生求职信
2014/01/30 职场文书
班级安全教育实施方案
2014/02/23 职场文书
JVM之方法返回地址详解
2022/02/28 Java/Android
HTML常用标签超详细整理
2022/03/19 HTML / CSS
Ruby处理CSV数据方法详解
2022/04/18 Ruby