debounce是vue1.x版本中数据双向绑定v-model的一个参数,在后来的版本中被舍弃了,因为最初用来控制Ajax请求以及一些高耗任务,它的用法是接受一个数值n,当视图层的数据改变后,延迟n毫秒后,数据层的数据再发生变化。
举个简单的例子,现在我们做一个搜索提示,页面上有一个搜索框,当我们输入信息的时候,下面能显示出来与信息相关的提示。首先将页面上的输入框与数据层的数据进行双向绑定,然后在Vue对这个数据进行监听,当数据发生变化的时候,把他发送到后台去获取提示信息,获取到后台的提示信息渲染到搜索提示框的下面,这也就完成了一个搜索提示。
那么这么做有什么问题呢?
这样做的话,当用户输入时每敲击一下键盘,就向后台发送一个数据请求,而前几次的请求基本没有用,浪费前台和后台的资源。我们应该等用户把信息输入完成后,在向后台去获取数据。那该怎么做呢?
debounce参数是这样做的,假设我们为页面上的输入框设置了debounce参数为1000,现在我在搜索框内输入了一个值,这时候数据并不会马上同步到数据层,而是在1000毫秒之后才同步到数据层。这样的话,当输入的时候并不会去获取数据,而是在输入动作停止1秒之后,再向后台去获取数据,只发送一次请求即可。
这样得搜索提示是不是看起来很完美?
错,我们需要控制的高耗任务是什么?我们需要控制什么时候向后台发送数据请求,而不是视图层的数据何时同步到数据层。这时debounce的局限性就显而易见了,使用了debounce就无法实时的获取到用户输入的信息,如果想对输入信息进行实时监测就无法实现。因此我们应该仅仅只延迟我们想要控制的操作,避免这些局限性。
说了这么多了,现在你应该非常的清楚了,debounce参数只是控制了状态更新的频率,而不是控制了高耗任务本身,所以新版本中debounce与Vue进行了解耦。那么我们该如何控制高耗任务本身呢?还以搜索提示为例子,看下面代码:
<template>
<div>
<input v-model="searchQuery" placeholder="请输入搜索内容">
<br>
<strong>{{ resTooltips }}</strong>
</div>
</template>
<script>
let _ = require('lodash'); //引入lodash,使用lodash下的debounce函数消抖
export default {
data() {
return {
searchQuery: "",
typing: false,
searching: false
};
},
computed: {
resTooltips: function() {
if (this.searching) {
return "⟳ 假装搜索中";
} else if (this.typing) {
return "... 输入中";
} else {
return "✓ 假装这里是搜索结果";
}
}
},
watch: {
searchQuery: function() {
this.typing = true;
this.expensiveOperation();
}
},
methods: {
// 这是 debounce 实现的地方。
expensiveOperation: _.debounce(function() {
this.searching = true;
setTimeout(
function() {
this.searching = false;
this.typing = false;
}.bind(this),
1000
);
}, 500)
}
};
</script>
debounce与Vue解耦,在vue-cli里要想使用debouce,得先安装lodash再引入一下。
用node的安装方法:
mpn i lodash --save
说了这么多,看效果图:
其实说了这么多,总结起来就一句话,debounce消抖在v-model中没有任何意义,所以Vue解除了与debounce的耦合,如果需要消抖,就自己引入lodash,在合适的地方去控制你的高耗任务。