Vue 利用指令实现禁止反复发送请求

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

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

    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, 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中也可以用一个数据来记录请求。

原文地址:https://www.cnblogs.com/youyouluo/p/11520783.html

时间: 2024-11-15 09:42:43

Vue 利用指令实现禁止反复发送请求的相关文章

更好一点的:Vue 利用指令实现禁止反复发送请求

理论上可以用于任何元素,生效时会在元素上出现一个同大小的灰色蒙层(button元素会该表原生的disabled属性). /** * 当元素触发发起请求后,当发起的请求中最后一个请求的结果返回(不关心返回顺序和结果),解锁元素禁用. * 优化:用一个pending记录所有请求,逐个判定是否返回结果. * 指令的方式使用轮询去校验接口是否返回结果,也可以在axios拦截器中,改变store中的数据, * 然后在页面的computed中处理,不过页面内代码不如一个指令来的方便. * 也可以用Bus来代

vue-resource发送请求

<!DOCTYPE html> <html> <head> <title>vue-resource</title> <meta charset="utf-8"> </head> <body> <div id="app"> <input type="button" value="get请求" @click="

Android开发:利用AlarmManager不间断向服务器发送请求以及notification通知

一.前言 嗯,其实需求很简单,但是因为服务器不会主动联系客户端,所以客户端必须不间断的向服务器请求以便得到一些数据,突然不知道怎么描述这个问题了,总之,我是通过AlarmManager来实现客户端不断地向服务器发送请求,好吧,往下. 二.实现 客户端不断的发请求,然后通过获得的响应做一些处理就可以了,流程就简简单单的像下面这个图. 第一步:利用AlarmManager开启轮询服务 public class MyAlarmManager { //开启轮询服务 public static void

利用postman进行接口测试并发送带cookie请求的方法

做web测试的基本上都用用到postman去做一些接口测试,比如测试接口的访问权限,对于某些接口用户A可以访问,用户B不能访问:比如有时需要读取文件的数据.在postman上要实现这样测试,我们就必要要用到cookie请求.用postman发送带cookie的请求,由于chrome安全的限制,postman是发不出带cookie的请求.如果想要发送带cookie的请求,需要开启postman Interceptor. 什么是POSTMAN? POSTMAN是一个Chrome插件工具,我们可以通过

Vue发送请求

可以试试玩ajax请求,个人觉得axios用Promise包装了下,代码美观 axios请求使用方法; https://www.npmjs.com/package/axios-es6 1.npm install axios -save, 在mian.js中引入 import Axios from 'axios' Vue.prototype.$axios = Axios 2.发送请求,遍历数据 <template> <div> <ul> <li v-for=&quo

Vue中监听窗口关闭事件并在窗口关闭前发送请求

Vue中监听窗口关闭事件并在窗口关闭前发送请求,代码如下: mounted() { window.addEventListener('beforeunload', e => this.beforeunloadHandler(e)) window.addEventListener('unload', e => this.unloadHandler(e)) }, destroyed() { window.removeEventListener('beforeunload', e => thi

Java爬虫(一)利用GET和POST发送请求,获取服务器返回信息

本人所使用软件 eclipse fiddle UC浏览器 分析请求信息 以知乎(https://www.zhihu.com)为例,模拟登陆请求,获取登陆后首页,首先就是分析请求信息. 用UC浏览器F12,点击Network,按F5刷新.使用自己账号登陆知乎后,点www.zhihu.com网址后,出现以下界面  在General中,看到请求方式是GET,在fiddle里请求构造中,方法选定GET. 下拉后,看到Request Header,将里面所有的内容复制下来,粘贴到fiddle的请求构造里 

在vue中使用axios实现跨域请求并且设置返回的数据的格式是json格式,不是jsonp格式

在vue中使用axios实现跨域请求 需求分析:在项目中需要抓取qq音乐的歌曲列表的数据,由于要请求数据的地址url=https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg.从qq音乐的官网上可以看到该请求的请求头中的referer中的域名是y.qq.com(发送请求页面的域名),而host的域名是c.y.qq.com(被请求页面的域名),由于两者不一样,所以不能通过前端直接发送请求给qq服务器去拿数据.这时候需要服务器做一个代理

Postman使用手册1——导入导出和发送请求查看响应

现在的web和移动开发,常常会调用服务器提供restful接口进行数据请求,为了调试,一般会先用工具进行测试,通过测试后才开始在开发中使用.这里介绍一下如何在chrome浏览器利用postman应用进行restful api接口请求测试. 一.导入导出打包的应用 在Postman中导入导出我们的 测试数据包 和 工作环境 非常的方便: 导出数据包: 导出数据包.png 导出工作环境: 导出工作环境 1.png 导出工作环境 2.png 导入数据包: 导入数据包.png 导入工作环境: 导入工作环