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权威指南 学习笔记之javascript数据类型
Sep 24 Javascript
下拉菜单点击实现连接跳转功能的js代码
May 19 Javascript
jquery实现保存已选用户
Jul 21 Javascript
使用jquery操作session方法分享
Jan 22 Javascript
Node.js实用代码段之获取Buffer对象字节长度
Mar 17 Javascript
浅谈javascript:两种注释,声明变量,定义函数
Oct 05 Javascript
纯JavaScript手写图片轮播代码
Oct 20 Javascript
浅谈js中的变量名和函数名重名
Feb 13 Javascript
vue-router 手势滑动触发返回功能
Sep 30 Javascript
layui实现显示数据表格、搜索和修改功能示例
Jun 03 Javascript
使用 Github Actions 自动部署 Angular 应用到 Github Pages的方法
Jul 20 Javascript
vue中路由跳转不计入history的操作
Sep 21 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引用地址改变变量值的问题
2012/03/23 PHP
PHP原生模板引擎 最简单的模板引擎
2012/04/25 PHP
深入解析Session是否必须依赖Cookie
2013/08/02 PHP
PHP验证码函数代码(简单实用)
2013/09/29 PHP
php将print_r处理后的数据还原为原始数组的解决方法
2016/11/02 PHP
PHP + plupload.js实现多图上传并显示进度条加删除实例代码
2017/03/06 PHP
js 第二代身份证号码的验证机制代码
2011/05/12 Javascript
Javascript跨域请求的4种解决方式
2013/03/17 Javascript
浅谈javascript中字符串String与数组Array
2014/12/31 Javascript
Javascript中实现trim()函数的两种方法
2015/02/04 Javascript
jQuery使用prepend()方法在元素前添加内容用法实例
2015/03/26 Javascript
CSS图片响应式 垂直水平居中
2015/08/14 Javascript
z-blog SyntaxHighlighter 长代码无法换行解决办法(基于jquery)
2015/11/18 Javascript
深入浅析Vue不同场景下组件间的数据交流
2017/08/15 Javascript
js禁止Backspace键使浏览器后退的实现方法
2017/09/01 Javascript
详解react、redux、react-redux之间的关系
2018/04/11 Javascript
微信小程序实现点赞、取消点赞功能
2018/11/02 Javascript
[00:35]DOTA2上海特级锦标赛 VP战队宣传片
2016/03/04 DOTA
Python实现复杂对象转JSON的方法示例
2017/06/22 Python
详解Python3 中hasattr()、getattr()、setattr()、delattr()函数及示例代码数
2018/04/18 Python
flask中过滤器的使用详解
2018/08/01 Python
django框架实现模板中获取request 的各种信息示例
2019/07/01 Python
python处理document文档保留原样式
2019/09/23 Python
Python使用grequests(gevent+requests)并发发送请求过程解析
2019/09/25 Python
python 多进程和协程配合使用写入数据
2020/10/30 Python
html标签之Object和EMBED标签详解
2013/07/04 HTML / CSS
HTML5 Canvas旋转动画的2个代码例子(一个旋转的太极图效果)
2014/04/10 HTML / CSS
德国婴儿推车和儿童安全座椅商店:BABYSHOP
2016/09/01 全球购物
一份全面的PHP面试问题考卷
2012/07/15 面试题
给医务人员表扬信
2014/01/12 职场文书
项目建议书模板
2014/05/12 职场文书
社保转移委托书范本
2014/10/08 职场文书
2015年医药代表工作总结
2015/04/25 职场文书
2016年清明节网上祭英烈活动总结
2016/04/01 职场文书
什么是检讨书?检讨书的格式及范文
2019/11/05 职场文书
三十年再续同学情倡议书
2019/11/27 职场文书