博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Vue 利用指令实现禁止反复发送请求
阅读量:5117 次
发布时间:2019-06-13

本文共 2643 字,大约阅读时间需要 8 分钟。

  前端做后台管控系统,在某些接口请求时间过长的场景下,需要防止用户反复发起请求。

  假设某场景下用户点击查询按钮后,后端响应需要长时间才能返回数据。那么要规避用户返回点击查询按钮无外乎是让用户无法在合理时间内再次点击按钮。实现方式也有好几种:

    1、在按钮点击发起请求后,弹个蒙层,显示个loading,等请求数据返回了将蒙层隐藏掉。

    2、在按钮点击发起请求后,将按钮禁用掉,同样等数据返回了将按钮禁用解除。

  以上是比较常见的2种方案。

  实现上最简单的肯定是在需要的页面种在请求前和拿到数据后,单独处理。这种方案优点仅仅是简单,但是每个需要处理的页面都要单独写一串重复的代码,哪怕利用mixin也要多不少冗余代码。

  如果是利用指令的方式仅仅需要在合适的地方加上个一条v-xxxx,其他都在指令的逻辑内统一处理。

  以第二种方式为例:

    

clickForbidden.jslet 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.jsimport axios from 'axios';export baseURL = 'xxxx';const api = axios.create({  baseURL,  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.jslet 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中也可以用一个数据来记录请求。

 

转载于:https://www.cnblogs.com/youyouluo/p/11520783.html

你可能感兴趣的文章
2016.3.31考试心得
查看>>
mmap和MappedByteBuffer
查看>>
Linux的基本操作
查看>>
转-求解最大连续子数组的算法
查看>>
对数器的使用
查看>>
【ASP.NET】演绎GridView基本操作事件
查看>>
ubuntu无法解析主机错误与解决的方法
查看>>
尚学堂Java面试题整理
查看>>
MySQL表的四种分区类型
查看>>
[BZOJ 3489] A simple rmq problem 【可持久化树套树】
查看>>
STM32单片机使用注意事项
查看>>
swing入门教程
查看>>
好莱坞十大导演排名及其代表作,你看过多少?
查看>>
Loj #139
查看>>
hihocoder1187 Divisors
查看>>
Azure 托管镜像和非托管镜像对比
查看>>
js window.open 参数设置
查看>>
032. asp.netWeb用户控件之一初识用户控件并为其自定义属性
查看>>
Ubuntu下安装MySQL及简单操作
查看>>
前端监控
查看>>