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 相关文章推荐
actionscript与javascript的区别
May 25 Javascript
JS+CSS实现可拖动的弹出提示框
Feb 16 Javascript
javascript实时显示当天日期的方法
May 20 Javascript
jquery模拟进度条实现方法
Aug 03 Javascript
jQuery绑定事件的几种实现方式
May 09 Javascript
js绘制购物车抛物线动画
Nov 18 Javascript
BOM之navigator对象和用户代理检测
Feb 10 Javascript
使用重写url机制实现验证码换一张功能
Aug 01 Javascript
JS实现电商放大镜效果
Aug 24 Javascript
Vue2实时监听表单变化的示例讲解
Aug 30 Javascript
JavaScript实现的联动菜单特效示例
Jul 08 Javascript
在node环境下parse Smarty模板的使用示例代码
Nov 15 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开发入门教程之面向对象
2006/12/05 PHP
解析PHP无限级分类方法及代码
2013/06/21 PHP
PHP文件缓存内容保存格式实例分析
2014/08/20 PHP
php+ajax实现的点击浏览量加1
2015/04/16 PHP
Yii框架表单模型和验证用法
2016/05/20 PHP
JavaScript面向对象编程
2008/03/02 Javascript
jQuery语法高亮插件支持各种程序源代码语法着色加亮
2013/04/27 Javascript
jquery利用命名空间移除绑定事件的方法
2015/03/11 Javascript
解决jQuery ajax请求在IE6中莫名中断的问题
2016/06/20 Javascript
js图片放大镜效果实现方法详解
2020/10/28 Javascript
详解vue的数据binding绑定原理
2017/04/12 Javascript
详解IWinter 一个路由转控制器的 Nodejs 库
2017/11/15 NodeJs
纯js代码生成可搜索选择下拉列表的实例
2018/01/11 Javascript
element日历calendar组件上月、今天、下月、日历块点击事件及模板源码
2020/07/27 Javascript
[12:29]2018国际邀请赛 开幕秀
2018/08/22 DOTA
Python读写Excel文件的实例
2013/11/01 Python
在Python中封装GObject模块进行图形化程序编程的教程
2015/04/14 Python
Python控制多进程与多线程并发数总结
2016/10/26 Python
Python调用ctypes使用C函数printf的方法
2017/08/23 Python
python smtplib发送带附件邮件小程序
2018/05/22 Python
Python SQL查询并生成json文件操作示例
2018/08/17 Python
对python自动生成接口测试的示例讲解
2018/11/30 Python
Jupyter notebook在mac:linux上的配置和远程访问的方法
2019/01/14 Python
Python帮你微信头像任意添加装饰别再@微信官方了
2019/09/25 Python
Django认证系统user对象实现过程解析
2020/03/02 Python
python爬虫开发之urllib模块详细使用方法与实例全解
2020/03/09 Python
Django在Model保存前记录日志实例
2020/05/14 Python
Python调用.net动态库实现过程解析
2020/06/05 Python
最新大学毕业求职简历的自我评价
2013/10/18 职场文书
给儿子的表扬信
2014/01/15 职场文书
产品发布会策划方案
2014/05/12 职场文书
大学生见习期满自我鉴定
2014/09/13 职场文书
结婚通知短信大全
2015/04/17 职场文书
创业计划书之网吧
2019/10/10 职场文书
python pygame入门教程
2021/06/01 Python
HDFS免重启挂载新磁盘
2022/04/06 Servers