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 相关文章推荐
java script编程起步(第三课)
Jan 10 Javascript
JavaScript将字符串转换为整数的方法
Apr 14 Javascript
jQuery往返城市和日期查询实例讲解
Oct 09 Javascript
Javascript基于对象三大特性(封装性、继承性、多态性)
Jan 04 Javascript
基于Echarts 3.19 制作常用的图形(非静态)
May 19 Javascript
jQuery css() 方法动态修改CSS属性
Sep 25 Javascript
Bootstrap框架安装使用详解
Jan 21 Javascript
详解基于webpack2.x的vue2.x的多页面站点
Aug 21 Javascript
分享ES6的7个实用技巧
Jan 18 Javascript
浅谈webpack打包生成的bundle.js文件过大的问题
Feb 22 Javascript
React 组件间的通信示例
Jun 14 Javascript
如何在JavaScript中优雅的提取循环内数据详解
Mar 04 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实现的短网址算法分享
2014/06/20 PHP
PHP基于DOM创建xml文档的方法示例
2017/02/08 PHP
JavaScript中的对象化编程
2008/01/16 Javascript
jQuery弹出(alert)select选择的值
2013/04/21 Javascript
js实现ArrayList功能附实例代码
2014/10/29 Javascript
jquery+javascript编写国籍控件
2015/02/12 Javascript
JavaScript判断表单提交时哪个radio按钮被选中的方法
2015/03/21 Javascript
JavaScript中的getDay()方法使用详解
2015/06/09 Javascript
整理Javascript基础入门学习笔记
2015/11/29 Javascript
基于JavaScript实现TAB标签效果
2016/01/12 Javascript
JavaScript使用Range调色及透明度实例
2016/09/25 Javascript
探讨AngularJs中ui.route的简单应用
2016/11/16 Javascript
JavaScript 监控微信浏览器且自带返回按钮时间
2016/11/27 Javascript
深入学习jQuery中的data()
2016/12/22 Javascript
Vue.js双向绑定实现原理详解
2016/12/22 Javascript
jQuery.cookie.js使用方法及相关参数解释
2017/03/06 Javascript
Vue 组件间的样式冲突污染
2017/08/31 Javascript
jQuery实现图片上传预览效果功能完整实例【测试可用】
2018/05/28 jQuery
关于vue组件事件属性穿透详解
2019/10/28 Javascript
微信小程序在text文本实现多种字体样式
2019/11/08 Javascript
vue中利用three.js实现全景图的完整示例
2020/12/07 Vue.js
[45:52]2018DOTA2亚洲邀请赛 4.1小组赛 A组加赛 LGD vs Liquid
2018/04/02 DOTA
PyQt5实现无边框窗口的标题拖动和窗口缩放
2018/04/19 Python
python顺序执行多个py文件的方法
2019/06/29 Python
python实现对服务器脚本敏感信息的加密解密功能
2019/08/13 Python
python工具——Mimesis的简单使用教程
2021/01/16 Python
基于CSS3实现的黑色个性导航菜单效果
2015/09/14 HTML / CSS
用HTML5制作一个简单的弹力球游戏
2015/05/12 HTML / CSS
Stefania Mode英国:奢华设计师和时尚服装
2017/10/23 全球购物
关于递归的一道.NET面试题
2013/05/12 面试题
大学军训感言
2014/01/10 职场文书
公司前台辞职报告
2014/01/19 职场文书
勾股定理课后反思
2014/04/26 职场文书
放飞理想演讲稿
2014/09/09 职场文书
2014年计划生育协会工作总结
2014/11/14 职场文书
深入理解Pytorch微调torchvision模型
2021/11/11 Python