vue自定义全局指令实现节流

vue自定义全局指令实现节流

我想通过vue的全局指令实现button click事件节流的功能

ChatGPT

在Vue中,你可以通过自定义全局指令来实现按钮点击事件的节流功能。节流(throttling)是指在一定时间间隔内只执行一次函数,以控制事件处理的频率,防止过多的函数调用。

以下是一个实现按钮点击事件节流的全局指令示例:

// main.js (或者在你的 Vue 项目中合适的位置注册全局指令)
import Vue from 'vue';

// 全局指令名称为 v-throttle-click
Vue.directive('throttle-click', {
  inserted: function (el, binding) {
    let throttleTimeout;
    el.addEventListener('click', () => {
      if (!throttleTimeout) {
        throttleTimeout = setTimeout(() => {
          throttleTimeout = null;
        }, binding.value || 1000); // 默认节流时间间隔为1秒,也可以通过传参来设置节流时间
      }
    });
  }
});

在上面的例子中,我们创建了一个名为 throttle-click 的全局指令。这个指令在按钮元素上进行了定义,用 inserted 钩子来添加事件监听器。在点击事件处理程序中,使用了 setTimeout 函数来实现节流功能。

使用方法如下:

<template>
  <div>
    <button v-throttle-click="1000" @click="handleClick">Click me (throttled)</button>
  </div>
</template>

<script>
export default {
  methods: {
    handleClick() {
      console.log('Button clicked (throttled)');
      // 这里放置你的点击事件处理逻辑
    }
  }
}
</script>

在上面的例子中,我们在按钮上应用了 v-throttle-click 指令,并传递了一个参数 1000,表示节流的时间间隔为1秒。你可以根据需要调整节流的时间间隔。每次点击按钮时,如果节流时间间隔内已经触发了一次点击事件,后续的点击将被忽略,直到节流时间间隔过去后重新生效。

这样,通过这个自定义的全局指令,你可以方便地在整个 Vue 项目中实现按钮点击事件的节流功能。

我想要对节流做一个优化,节流对首次事件的处理在时间间隔之后,而我希望首次点击时直接执行click事件,忽略首次点击后时间间隔内的其他点击

ChatGPT

如果你希望在按钮首次点击时立即执行点击事件,并且在之后的时间间隔内忽略其他点击事件,可以对节流函数稍作修改。这种需求可以通过结合节流和防抖(debounce)的思路来实现。

在这种情况下,我们需要记录首次点击的时间戳,并在首次点击后立即执行点击事件处理程序。之后的点击事件则需要在指定的时间间隔内被忽略。下面是修改后的全局指令实现:

// main.js (或者在你的 Vue 项目中合适的位置注册全局指令)
import Vue from 'vue';

// 全局指令名称为 v-throttle-click
Vue.directive('throttle-click', {
  inserted: function (el, binding) {
    let lastClickTime = 0;
    const throttleTimeout = binding.value || 1000; // 默认节流时间间隔为1秒,也可以通过传参来设置节流时间
    
    el.addEventListener('click', () => {
      const now = Date.now();
      if (now - lastClickTime >= throttleTimeout) {
        // 超过节流时间间隔,执行点击事件处理程序
        binding.value();
        lastClickTime = now;
      }
    });
  }
});

在这个示例中,我们记录了 lastClickTime 来保存上一次点击的时间戳。当点击事件发生时,我们首先计算当前时间戳 now,并检查距离上一次点击的时间间隔是否大于或等于节流时间间隔 throttleTimeout。如果是,则执行点击事件处理程序 binding.value(),并更新 lastClickTime 为当前时间戳。

使用方法保持不变:

<template>
  <div>
    <button v-throttle-click="handleClick">Click me (throttled)</button>
  </div>
</template>

<script>
export default {
  methods: {
    handleClick() {
      console.log('Button clicked (throttled)');
      // 这里放置你的点击事件处理逻辑
    }
  }
}
</script>

在这个示例中,我们不再传递时间间隔参数,而是直接将处理函数 handleClick 作为指令的值。这样,首次点击时会立即执行处理函数,之后的点击事件则会在指定的时间间隔内被节流。

实战

总结全局自定义指令的实现并解决您在 Vue 3 中遇到的问题。关键在于理解 Vue 3 的指令生命周期钩子名称变化,以及正确处理 binding.value 作为配置对象而不是单一函数。

1. 全局自定义指令的实现

首先,在 Vue 3 中定义全局自定义指令:

// src/directives/index.js
const throttleDirective = {
  mounted(el, binding) {
    let lastClickTime = 0
    console.log(binding)
    const throttleTimeout = 1000
    el.addEventListener('click', () => {
      const now = Date.now()
      if (now - lastClickTime >= throttleTimeout) {
        // 超过节流时间间隔,执行点击事件处理程序
        binding.value()
        lastClickTime = now
      }
    })
  },
}

export default {
  install(app) {
    app.directive('throttle', throttleDirective)
  },
}

2. 在 main.js 中注册全局自定义指令

确保在 main.js 中导入并注册这些指令:

import directives from '@/directives'; // 导入自定义指令

// 注册全局自定义指令
app.use(directives);

3. 父组件中使用指令

在父组件中使用指令时,需要传递包含 handlerdelay 的对象:

<template>
  <div>
    <a-button
      type="primary"
      class="btn"
      v-throttle="handleClick"
    >
      防抖
    </a-button>
  </div>
</template>

总结

  1. Vue 3 指令钩子:使用 mounted 钩子代替 Vue 2 中的 inserted 钩子。

  2. 解构 binding.value:在指令内部正确解构 binding.value 并设置默认值。

  3. 在本案例中直接将click事件传入binding,如果有其他参数,可以通过一个对象一起传入,在指令中解构

    <a-button  v-throttle="{ handler: handleClick, delay: 1000 }">
        防抖
    </a-button>
    // 传入
    const throttleDirective = {
      mounted(el, binding) {
        const { handler, delay = 1000 } = binding.value || {};
        // 解构
        el.addEventListener('click', (event) => {
            handler(event);
          }
        });
      }
    };
    

{
const { handler, delay = 1000 } = binding.value || {};
// 解构
el.addEventListener(‘click’, (event) => {
handler(event);
}
});
}
};

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JoveTAT

感谢您的支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值