Vue3 自定义指令实现元素点击的节流与输入框的防抖,后端老哥再也不用担心我频繁发送请求了

简介: Vue3 自定义指令实现元素点击的节流与输入框的防抖,后端老哥再也不用担心我频繁发送请求了

在我们项目开发的时候,很多时候都会用到节流和防抖来防止用户频繁操作从而造成资源与服务器的浪费。所以作为一个前端我们往往需要在合适的位置加上防抖或者节流。本篇文章将介绍如何使用 Vue3 自定义指令的方式实现元素点击节流指令v-throttleClick和输入框的防抖指令v-debounceInput


防抖和节流的定义



在开始之前,我们先了解一下什么是防抖,什么是节流。

防抖是指当你触发一个事件的时候,它的回调不会立即执行,而是在 n 秒之后执行,但当在这 n 秒之内你又触发了这个事件,则会重新计时,也就是你还需要再等 n 秒才会执行。

节流是指当你触发一个事件的时候,它会立刻执行回调,但是如果你在 n 秒之内再次触发,回调不再执行,也就是说单位时间内触发事件只会执行一次回调

了解了防抖和节流之再看如何实现v-throttleClickv-debounceInput


元素点击节流:v-throttleClick



我们先看下v-throttleClick要实现的效果:指令接受一个回调函数,当给元素绑定这个指令的时候,点击该元素则会以节流的形式触发改回调函数。同时接收一个 arg 作为节流事件,默认 1000ms

实现起来其实很简单

<template>
  <button v-throttleClick:2000="kfc50">点击V我50吃鸡脚</button>
</template>
<script setup>
const vThrottleClick = (el, bind) => {
  let isPass = true;
  el.addEventListener("click", () => {
    if (typeof bind.value !== "function") return;
    if (isPass) {
      bind.value();
      isPass = false;
      setTimeout(() => {
        isPass = true;
      }, bind.arg || 1000);
    }
  });
};
const kfc50 = () => {
  console.log("+50");
};
</script>

然后我们频繁点击按钮看效果

image.png

但是如果我们直接在回调函数中传参,函数就会立即执行,比如

<button v-throttleClick:2000="kfc50(1)">点击V我50吃鸡脚</button>

并且点击之后也不会进入逻辑判断,因为 bind.value 不再是个函数。所以如果有传参需求,则需要将回调写成高阶函数形式

const kfc50 = (arg1) => {
  return () => {
    console.log(arg1);
  };
};

到这里一个简单的v-throttleClic指令就完成了。那么它可以用作什么场景呢? 比如你有一个搜索按钮,你肯定不能在用户疯狂点击的时候一直发请求吧,那就加一个 v-throttleClick 指令吧


输入框防抖v-debounceInput



假如你有这样一个需求,用户不停的在输入框输入内容,当用户停止输入的时候再触发搜索向后台发送请求。这时候聪明的你一定想到了防抖(你慢慢抖吧,等你抖完了我再给请你吃 kfc)

同样的指令接收一个 arg 和 value,直接看代码实现

<template>
  <input v-debounceInput:500="toKfc" />
</template>
<script setup>
const vDebounceInput = (el, bind) => {
  if (typeof bind.value !== "function") return;
  bind.value.id = null;
  el.addEventListener("input", () => {
    clearTimeout(bind.value.id);
    bind.value.id = setTimeout(() => {
      bind.value();
    }, bind.arg || 1000);
  });
};
const toKfc = () => {
  console.log("优弧请我吃kfc");
};
</script>

然后我们看下效果

image.png


全局注册指令



如果我们想要在每个组件都能使用这两个指令,我们可以将其注册到全局。我们可以在 main.js 中进行注册,以 debounceInput 为例

import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
const app = createApp(App);
app.directive("debounceInput", (el, bind) => {
  if (typeof bind.value !== "function") return;
  bind.value.id = null;
  el.addEventListener("input", () => {
    clearTimeout(bind.value.id);
    bind.value.id = setTimeout(() => {
      bind.value();
    }, bind.arg || 1000);
  });
});
app.mount("#app");


写在最后



vue 的自定义指令在平时工作中用到的地方还是很多的,比如权限管理,事件埋点等等都可以使用指令实现,非常的方便,所以对 vue 自定义指令还不熟悉的小伙伴可以直接到官网查看文档


相关文章
|
2天前
|
资源调度 JavaScript 前端开发
vue封装请求
vue封装请求
17 0
|
2天前
|
Web App开发 前端开发 网络协议
API 请求慢?这次锅真不在后端
API 请求慢?这次锅真不在后端
|
2天前
|
JavaScript
vue页面加载时同时请求两个接口
vue页面加载时同时请求两个接口
|
2天前
|
前端开发 数据库 Python
使用 Python 的 Web 框架(如 Django 或 Flask)来建立后端接口,用于处理用户的请求,从数据库中查找答案并返回给前端界面
【1月更文挑战第13天】使用 Python 的 Web 框架(如 Django 或 Flask)来建立后端接口,用于处理用户的请求,从数据库中查找答案并返回给前端界面
99 7
|
2天前
|
XML JSON 前端开发
获取后端接口请求中的参数(@PathVariable,@RequestParam,@RequestBody区别,使用postman请求
获取后端接口请求中的参数(@PathVariable,@RequestParam,@RequestBody区别,使用postman请求
|
2天前
|
小程序 开发者
体验版小程序为何无法访问云端服务器后端接口(请求失败...(已完美解决附加图片))?
体验版小程序为何无法访问云端服务器后端接口(请求失败...(已完美解决附加图片))?
25 0
|
2天前
|
资源调度 前端开发 JavaScript
Vue3中如何使用axios进行Ajax请求?
Vue3中如何使用axios进行Ajax请求?
121 1
|
2天前
Vue3 配置代理和使用全局axios请求数据
Vue3 配置代理和使用全局axios请求数据
96 1
|
2天前
|
负载均衡 前端开发 Java
字节后端面试题(前端发送请求到后端的过程(MVC),网关gateway作用,怎么解决跨域,各微服务组件作用)
字节后端面试题(前端发送请求到后端的过程(MVC),网关gateway作用,怎么解决跨域,各微服务组件作用)
151 0
|
2天前
|
JavaScript
Vue如何请求接口——axios请求
Vue如何请求接口——axios请求
32 0