节流
动作绑定事件, 动作发生后一段时间再次触发事件, 在这段时间内, 如果动作又发生, 则无视该动作, 直到事件执行完成后, 才重新触发
简单: 以第一次为准, 一段间隔内一定会执行一次
export function throttle(func: (...args: any[]) => void, time: number) {
let activeTime = 0;
return function(this: void) {
const current = Date.now();
if (current - time > activeTime) {
func.call(this, ...arguments);
activeTime = Date.now();
}
};
}
防抖
动作绑定时间, 动作发生后一定时间后触发事件, 在这段时间内, 如果该时间再次发生, 则重新等待一段时间再触发事件
简而言之, 以最后一次触发的为准, 之前的忽略
export function debounce(func: (...args: any[]) => void, time: number) {
let timer: any = null;
return function(this: void) {
clearTimeout(timer);
timer = setTimeout(() => {
func.call(this, ...arguments);
}, time);
};
}
测试
<template>
<div class="hello">
<button
size="mini"
@click="addRow(msg)"
>添加</button
>
<ul>
<li v-for="(item, index) in list" :key="item.id">
<span>{{item.id}}</span>
<button
size="mini"
@click="deleteRow(item, index)"
>删除</button
>
</li>
</ul>
</div>
</template>
<script lang="ts">
mport { Component, Prop, Vue } from "vue-property-decorator";
import { throttle, debounce } from "../utils/utils";
@Component({
components: {}
})
export default class HelloWorld extends Vue {
private msg: string = 'hello world';
private list: Array<any> = [
{ id: 'a' },
{ id: 'b' },
{ id: 'c' },
{ id: 'd' }
];
// 以第一次为准, 每隔一段时间会执行
addRow = throttle((msg: string) => {
console.log("1", msg);
}, 2000);
// 疯狂点击, 只会执行一次
deleteRow = debounce((rowItem: object, index: number) => {
console.log("2", rowItem, index);
}, 2000);
}
</script>
原生js实现
function throttle() {
let activeTime = 0;
return function() {
const current = Date.now();
if (current - time > activeTime) {
func.apply(this, arguments);
activeTime = Date.now();
}
}
}
function debounce(func, time) {
let timer = null;
return function() {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arguments);
}, time);
}
}
// 必须切到node v12上版本支持 下列ES6语法
class Test {
debounceEvent = debounce(() => {
// Test实例对象
console.log(this);
}, 1000)
debounceEvent2 = debounce(function(msg) {
// window
console.log(this);
console.log(msg);
}, 1000)
throttleEvent = throttle(() => {
console.log(this);
}, 1000)
click() {
for (let i = 0; i < 10; i ++) {
this.debounceEvent2('携带参数');
}
}
}
const t = new Test();
t.click();