转载于vue官网
https://cn.vuejs.org/
https://zhuanlan.zhihu.com/p/72923073
防抖debounce
假设函数持续多次执行,我们希望让它冷静下来再执行。也就是当持续触发事件的时候,函数是完全不执行的,等最后一次触发结束的一段时间之后,再去执行
例如下面的例子:
在1000毫秒内,我们不停的在input中输入,则这1000毫秒内的函数总不会执行。每输入一次,这1000号码总会重置,当等待1000毫秒后,对应的函数才会执行。
节流throttle
节流的意思是让函数有节制地执行,而不是毫无节制的触发一次就执行一次。什么叫有节制呢?就是在一段时间内,只执行一次。
例如下面的例子:
我们不停的输入,但是每2000毫秒总会执行一次函数
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>侦听器</title>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
</head>
<body>
<div id="app">
<p>结果:</p>
<p>问一个回答 是或否的问题: <label><input type="text" v-model="question" v-bind:disabled='inputDisabled'></label>
</p>
<p>{{answer}}</p>
</div>
<script>
'use strict';
function debounce(func,delay){
let timeout
return function(){
clearTimeout(timeout)
timeout = setTimeout(() => {
func.apply(this,arguments)
}, delay);
}
}
function throttle(func, delay) {
let run = true
return function () {
if (!run) {
return // 如果开关关闭了,那就直接不执行下边的代码
}
run = false // 持续触发的话,run一直是false,就会停在上边的判断那里
setTimeout(() => {
func.apply(this, arguments)
run = true // 定时器到时间之后,会把开关打开,我们的函数就会被执行
}, delay)
}
}
let QAObj = {
question: '',
answer: 'I cannot give you an answer until you ask a question!',
inputDisabled: false
};
let reg = /(\?$)|(?$)/;
let vm = new Vue({
el: '#app',
data: QAObj,
// 如果 `question` 发生改变,这个函数就会运行
watch: {
question: function () {
this.answer = 'Waiting for you to stop typing...';
this.throttle2();
}
},
methods: {
// `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
// 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
// AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
debounce1: _.debounce(function () {
this.answer = 'Thinking ... ';
this.inputDisabled = true;
axios.get('https://yesno.wtf/api')
// then中的函数如果不是箭头函数,则需要对this赋值self
.then((response) => {
this.answer = _.capitalize(response.data.answer);
this.inputDisabled = false;
this.$el.focus()
})
.catch((error) => {
this.answer = 'Error! Could not reach the API. ' + error;
this.inputDisabled = false;
this.$el.focus()
})
}, 1000), // 这是我们为判定用户停止输入等待的毫秒数
debounce2: debounce(function () {
this.answer = 'Thinking ... ';
this.inputDisabled = true;
axios.get('https://yesno.wtf/api')
// then中的函数如果不是箭头函数,则需要对this赋值self
.then((response) => {
this.answer = _.capitalize(response.data.answer);
this.inputDisabled = false;
this.$el.focus()
})
.catch((error) => {
this.answer = 'Error! Could not reach the API. ' + error;
this.inputDisabled = false;
this.$el.focus()
})
}, 1000), // 这是我们为判定用户停止输入等待的毫秒数
throttle1:_.throttle(function () {
this.answer = 'Thinking ... ';
this.inputDisabled = true;
axios.get('https://yesno.wtf/api')
// then中的函数如果不是箭头函数,则需要对this赋值self
.then((response) => {
this.answer = _.capitalize(response.data.answer);
this.inputDisabled = false;
this.$el.focus()
})
.catch((error) => {
this.answer = 'Error! Could not reach the API. ' + error;
this.inputDisabled = false;
this.$el.focus()
})
}, 2000),
throttle2: throttle(function () {
this.answer = 'Thinking ... ';
this.inputDisabled = true;
axios.get('https://yesno.wtf/api')
// then中的函数如果不是箭头函数,则需要对this赋值self
.then((response) => {
this.answer = _.capitalize(response.data.answer);
this.inputDisabled = false;
this.$el.focus()
})
.catch((error) => {
this.answer = 'Error! Could not reach the API. ' + error;
this.inputDisabled = false;
this.$el.focus()
})
}, 2000),
},
computed: {},
});
</script>
</body>
</html>