欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

vue以组件或者插件的形式实现throttle或者debounce

程序员文章站 2024-03-31 10:08:52
需求 在业务中,会碰到许多点击请求的情况,在请求前改变一个lock变量(在lock变回来之前,点击无效),在请求回调中再改变lock.以确保在,请求回来之前,不会重复请求...

需求

在业务中,会碰到许多点击请求的情况,在请求前改变一个lock变量(在lock变回来之前,点击无效),在请求回调中再改变lock.以确保在,请求回来之前,不会重复请求。或者类似的点击节流业务

实现方式

指令

 <div v-for="a in 3" :key="a" v-demo:getdata="a">指令</div>
 //getdata是函数名,a是传入的参数
  directives: {
  demo: {
   bind(el: element, binding: any, vnode: vnode) {
    const that: any = vnode.context
    // console.log(binding, vnode)
    // console.log(binding.arg, binding.value)
    if (!that[binding.arg].isbind){ // 打上标记,如果已经转换了,就不转了
     that[binding.arg] = deb(that[binding.arg])
     that[binding.arg].isbind = true
    }
    el.addeventlistener('click', function t(event: event): void{
     that[binding.arg](binding.value)
    })
   },
  },
 },

组件

子组件

<template>
 <div>
  <div @click="senclick">
   <slot></slot>
  </div>
 </div>
</template>
<script lang="ts">
import vue from 'vue';
import { component, prop } from 'vue-property-decorator';
@component({})
export default class child extends vue {
 @prop({ type: number, default: 500 }) public timeout!: number; // 时间
 @prop({ type: string, default: 'throttle' }) public type!: string; // 类型
 @prop() public params!: any; // 传入参数
 public message: string = 'hello';
 public throttlelock: boolean = false;
 public debouncelock: number = 0;
 public time: any;
 public senclick(): void {
  console.log(this.timeout, this.type, this.params);
  if (this.type === 'throttle') {
   if (this.throttlelock) {
    return;
   }
   this.throttlelock = true;
   settimeout(() => {
    this.throttlelock = false;
   }, this.timeout);
   this.$emit('myclick', this.params);
  } else if (this.type === 'debounce') {
   if (this.debouncelock) {
    cleartimeout(this.debouncelock);
   }
   this.debouncelock = settimeout(() => {
    this.$emit('myclick', this.params);
   }, this.timeout);
  } else {
   this.$emit('myclick', this.params);
  }
 }
}
</script>

<style scoped lang='stylus'>
div {
 width: 100%;
 height: 100%;
}
</style>

父组件

<template>
 <div class="home">
   <throttle-and-debounce @myclick="getdata" :time="500" type="throttle" params="123">
    <div>我是组件内容</div>
   </throttle-and-debounce>
 </div>
</template>
import { component, vue } from 'vue-property-decorator';
import throttleanddebounce from '@/components/throttleanddebounce.vue'; 
@component({
 components: {
  throttleanddebounce,
 },
})
export default class home extends vue {
public getdata(e: any){
   console.log('异步数据', e)
  }
}

</script>

plugin

函数

function deb(fn: function){
 let lock: number
 return (e) => {
  if (lock){
   cleartimeout(lock)
  }
  console.log('创建闭包延迟执行')
  lock = settimeout(() => {
   fn(e)
  }, 1500)
 }
}
export {deb}

组件内使用

<template>
 <div class="home">
  <div @click="func(123)">function</div>
 </div>
</template>
<script lang="ts">
import { component, vue } from 'vue-property-decorator';
import {deb} from '@/assets'
@component({
 components: {
  throttleanddebounce,
 },
})
export default class home extends vue {
   public beforecreate(){
     this.func = deb((e: {a: number}) => {
     console.log('this', e)
    })
   }
}
</script>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。