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 用原型继承来实现对象系统
Mar 22 Javascript
利用js正则表达式验证手机号,email地址,邮政编码
Jan 23 Javascript
jQuery验证插件 Validate详解
Nov 20 Javascript
了不起的node.js读书笔记之例程分析
Dec 22 Javascript
React Native模块之Permissions权限申请的实例相机
Sep 28 Javascript
MVVM框架下实现分页功能示例
Jun 14 Javascript
js中innerText/textContent和innerHTML与target和currentTarget的区别
Jan 21 Javascript
详解javascript 变量提升(Hoisting)
Mar 12 Javascript
webpack4.0+vue2.0利用批处理生成前端单页或多页应用的方法
Jun 28 Javascript
js实现图片3D轮播效果
Sep 21 Javascript
Vue 中 a标签上href无法跳转的解决方式
Nov 12 Javascript
JS使用setInterval计时器实现挑战10秒
Nov 08 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
PR值查询 | PageRank 查询
2006/12/20 PHP
DEDE采集大师官方留后门的删除办法
2011/01/08 PHP
关于PHP二进制流 逐bit的低位在前算法(详解)
2013/06/13 PHP
CentOS下PHP安装Oracle扩展
2015/02/15 PHP
PHP实现上传文件并存进数据库的方法
2015/07/16 PHP
Javascript SHA-1:Secure Hash Algorithm
2006/12/20 Javascript
javascript实现的距离现在多长时间后的一个格式化的日期
2009/10/29 Javascript
js 获取后台的字段 改变 checkbox的被选中的状态 代码
2013/06/05 Javascript
基于javascript、ajax、memcache和PHP实现的简易在线聊天室
2015/02/03 Javascript
跟我学习javascript的var预解析与函数声明提升
2015/11/16 Javascript
jQuery之动画效果大全
2016/11/09 Javascript
js数组操作方法总结(必看篇)
2016/11/22 Javascript
探讨跨域请求资源的几种方式(总结)
2016/12/02 Javascript
详解jquery validate实现表单验证 (正则表达式)
2017/01/18 Javascript
基于zepto.js实现手机相册功能
2017/07/11 Javascript
vue实现滑动切换效果(仅在手机模式下可用)
2020/06/29 Javascript
JavaScript实现无限轮播效果
2020/11/19 Javascript
《Python之禅》中对于Python编程过程中的一些建议
2015/04/03 Python
python杀死一个线程的方法
2015/09/06 Python
理解Python中的With语句
2016/03/18 Python
Python基于win32ui模块创建弹出式菜单示例
2018/05/09 Python
Python将字符串常量转化为变量方法总结
2019/03/17 Python
python支持多线程的爬虫实例
2019/12/21 Python
解决c++调用python中文乱码问题
2020/07/29 Python
Python headers请求头如何实现快速添加
2020/11/03 Python
Clarins娇韵诗美国官网:法国天然护肤品牌
2016/09/26 全球购物
德国黑胶唱片、街头服装及运动鞋网上商店:HHV
2018/08/24 全球购物
美国滑雪板和装备购物网站:Skis.com
2018/12/20 全球购物
俄罗斯奢侈品牌衣服、鞋子和配饰的在线商店:INTERMODA
2020/07/17 全球购物
党课学习思想汇报
2014/01/02 职场文书
《美丽的彩虹》教学反思
2014/02/25 职场文书
2014年加油站站长工作总结
2014/12/23 职场文书
python文件名批量重命名脚本实例代码
2021/04/22 Python
Python爬虫之爬取二手房信息
2021/04/27 Python
Pyhton模块和包相关知识总结
2021/05/12 Python
mysql事务隔离级别详情
2021/10/24 MySQL