key point:
- The writing method of vue is a bit different from ordinary ones, because this of vue is not only the current component object, but also inherits the vue object upwards (the difference can be seen below)
- call and apply can only inherit from the parent, not deep inheritance
- Because deep inheritance requires recursive or multi-layer nested functions, the code volume is large and difficult to maintain, so the following method is recommended
1. Anti-shake (debounce)
- Meaning: After the high-frequency time is triggered, the function will only be executed once within n seconds. If the high-frequency time is triggered again within n seconds, the time will be recalculated.
It is a continuous process. For example, it is limited to 1s, executed once, and the next execution is 1s, that is, the function is executed when the user stops the operation; as long as the operation is not stopped, the operation in the function will never be executed
- Usage scenario: anti-shake is often applied to users to search and input to save request resources, and anti-shake is only triggered once when an event
window
is triggeredresize
- code:
/**
* @description 函数防抖 触发高频时间后n秒内函数只会执行一次,如果n秒内高频时间再次触发,则重新计算时间。
* @param {Function} func 需要执行的函数
* @param {Number} wait 间隔时间 默认200ms
* @param {Boolean} immediate 是否立即执行 true(默认) 表立即执行,false 表非立即执行
* @return {*}
* @author liuxin
*/
export function VueDebounce(func, wait = 200, immediate = true) {
let timeout = null; // 定时器
return function () {
let that = this, // this对象
args = arguments; // 参数
if (timeout) clearTimeout(timeout);
if (immediate === true) { // 立即执行
var callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, wait)
if (callNow) {
// func.apply(that, args); // 普通用法 vue3用法
that[func](...args); // vue2用法
}
}
else { // 非立即执行
timeout = setTimeout(() => {
// func.apply(this, args); // 普通用法 vue3用法
that[func](...args); // vue2用法
}, wait);
}
}
}
-
Usage Vue2
methods: {
/**
* 点击事件 函数防抖
* 用法:<el-button @click="debounceHandel">点击测试</el-button>
*/
debounceHandel: VueDebounce("handlerFunc"),
/**
* 点击事件:真正执行的函数
*/
handlerFunc(type) {
console.log("测试防抖事件");
this.$emit("click","这是参数"); // 如果用普通用法,则这里会找不到$emit,因为this还往上继承了vue的对象
},
}
-
Usage vue3
<el-button type="primary" size="default" @click="cleanHandle">测试防抖</el-button>
export default {
setup() {
const state = reactive({
});
/**
* @description: 一秒执行一次
* @Author: liuxin
*/
const cleanHandle = VueDebounce(() => {
scoket.send(
JSON.stringify({
api: "clear_count",
})
);
}, 1000);
return {
...toRefs(state),
cleanHandle,
};
},
};
2. Throttle
- Meaning: High-frequency time trigger, but it will only be executed once in n seconds, so throttling will dilute the execution frequency of the function. . It is a fixed process. If it is limited to 1s, it will only be executed once within 1s. No matter what, the corresponding operation will be executed within 1s.
- Usage scenario: Similar to the anti-shake usage scenario, the key is that feedback is required within a fixed time (1s), and feedback usage throttling is required, that is: regardless of whether the user stops the operation, the function operation will be executed at a fixed time
- Code: The usage is consistent with the function anti-shake
import { ElMessage } from "element-plus";
import "element-plus/es/components/message/style/css"
/**
* @description 函数节流
* @param {Function} func 函数
* @param {Number} wait 延迟执行毫秒数,默认200
* @param {Number} type 1 表时间戳版,2 表定时器版
*/
function VueThrottle(func, wait=200 ,type) {
if(type===1){
let previous = 0;
}else if(type===2){
let timeout;
}
return function() {
let that= this;
let args = arguments;
if(type===1){
let now = Date.now();
if (now - previous > wait) {
// func.apply(that, args); // 普通用法
that[func](...args); // vue用法
previous = now;
ElMessage.closeAll(); // 关闭所有弹窗
}
else {
ElMessage.error("操作太频繁了哦,稍后再试");
}
}else if(type===2){
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
// func.apply(that, args)
that[func](...args); // vue用法
ElMessage.closeAll();// 关闭所有弹窗
}, wait)
}
else {
ElMessage.error("操作太频繁了哦,稍后再试");
}
}
}
}