当前位置: 首页 > 科技观察

偷偷飞起来,在Vue中使用防抖和节流

时间:2023-03-13 02:14:52 科技观察

在监听频繁触发的事件时要小心,例如用户在输入框输入,窗口调整大小,滚动,IntersectionObserver事件。这些事件总是经常触发,可能每隔几秒触发一次。为每个事件发起一个获取请求(或类似的东西)是不明智的。我们需要做的就是减慢事件处理程序的执行速度。这种缓冲技术是去抖和节流[1]。在本文中,您将学习如何使用debounce和throttle来控制Vue组件中的观察者和事件处理程序。1.观察者防抖我们先从一个简单的组件开始。我们的任务是将用户输入文本框的文本输出到控制台:打开演示[2]打开演示,在输入框中输入几个字符。每次输入该值时都会将其记录到控制台。我们通过使用观察器来监听值数据属性来实现日志记录。但是如果你想在观察者回调中添加一个带有值作为参数的GET请求,那么你不应该期望太频繁地发出请求。下面针对打印控制台日志的行为做一下防抖。核心思想是创建一个去抖动函数,然后在观察者内部调用该函数。我在这里选择了“lodash.debounce”去抖动实现,但您可以自由选择您喜欢的实现。让我们将去抖逻辑应用于组件:试试demo[3]如果你打开这个demo,你会发现从用户的角度来看,并没有太大的变化:你仍然可以像之前的demo一样自由输入字符。但有一个区别:新的输入值仅在最后一次输入后500毫秒记录到控制台。这意味着防抖已经生效。观察者的debounce实现只需要3个简单的步骤:在create()钩子中,创建debounce回调并将其分配给实例:this.debouncedWatch=debounce(...,500)。在观察者回调中watch.value(){...}使用正确的参数调用this.debouncedWatch()。最后,在beforeUnmount()挂钩中调用this.debouncedWatch.cancel()以在卸载组件之前取消所有挂起的去抖功能的执行。以同样的方式,您可以对任意数据属性的观察者应用去抖动。然后就可以放心的在防抖回调里面进行一些重操作了,比如网络请求,重DOM操作等等。2.事件处理器防抖上一节我展示了观察者如何使用防抖,那么常规的事件处理器呢?我们重用了前面的用户在输入字段中输入数据的示例,但是这次我们将向输入字段添加一个事件处理程序。和往常一样,如果不采取任何缓冲措施,每当修改值时,都会打印到控制台:尝试演示[4]打开这个演示,在输入框中输入几个字符。查看控制台:您会注意到每次键入时都会打印日志。此外,如果您将执行一些繁重的操作(例如网络请求),它也不适合。事件处理器使用debounce可以参考:尝试演示[5]打开演示并输入一些字符。该组件将在最后一次输入后仅500毫秒将新的输入值记录到控制台。防抖又起作用了!事件处理程序的debounce实现只需要3个步骤:.在create()钩子中,创建实例后,立即将去抖动回调debounce(event=>{...},500)分配给this.debouncedHandler。将debouncedHandler分配给输入框模板中的v-on:input:debouncedHandler.cancel(),取消所有挂起的函数调用。另一方面,这些示例应用了防抖技术。但是,可以使用相同的方法来创建节流函数。3、注意你可能不明白:为什么不直接在组件的方法选项中创建防抖功能,然后在模板中调用这些方法作为事件处理器呢?//...方法:{//为什么不呢?debouncedHandler:debounce(function(){...}},500)}//...这比在实例对象上创建去抖动函数要简单得多。例如:试试debounce[6]这次不在debounce回调是在created()钩子中创建,但debounce回调分配给methods.debouncedHandler。如果您尝试演示,您会发现它有效!问题是,组件使用exportdefault{...}导出的选项对象(包括方法)将被组件实例重用。如果页面中有超过2个组件实例,那么所有组件将应用相同的去抖动函数methods.debouncedHandler—这将导致去抖动失败。4.总结在Vue中,你可以很方便的对观察者和事件处理者进行防抖和节流。核心逻辑是,在created()hook中,创建一个防抖或节流回调,并赋值给实例。//...created(){this.debouncedCallback=debounce((...args)=>{//去抖回调},500);},//...A)然后在观察者Debounce函数中调用实例on://...watch:{value(...args){this.debouncedCallback(...args);},},//...B)或设置事件处理程序:在此之后,每次this.debouncedCallback(...args)被调用,即使执行频率很高,也可以缓冲内部回调。