問題描述
搜索輸入框中,只當用戶停止輸入后,才進行后續的操作,比如發起Http請求等。
學過電子電路的同學應該知道按鍵防抖。原理是一樣的:就是說當調用動作n毫秒后,才會執行該動作,若在這n毫秒內又調用此動作則將重新計算執行時間。本文將分別探討在angular.js和vue.js中如何實現對用戶輸入的防抖。
angular.js中解決方案
把函數防抖Debounce寫成一個service,方便多處調用:
.factory('debounce', ['$timeout','$q', function($timeout, $q) {
// The service is actually this function, which we call with the func
// that should be debounced and how long to wait in between calls
return function debounce(func, wait, immediate) {
var timeout;
// Create a deferred object that will be resolved when we need to
// actually call the func
var deferred = $q.defer();
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if(!immediate) {
deferred.resolve(func.apply(context, args));
deferred = $q.defer();
}
};
var callNow = immediate && !timeout;
if ( timeout ) {
$timeout.cancel(timeout);
}
timeout = $timeout(later, wait);
if (callNow) {
deferred.resolve(func.apply(context,args));
deferred = $q.defer();
}
return deferred.promise;
};
};
}])
調用方法,在需要使用該功能的controller/directive中注入debounce,也要注入$watch,然后:
$scope.$watch('searchText',debounce(function (newV, oldV) {
console.log(newV, oldV);
if (newV !== oldV) {
$scope.getDatas(newV);
}
}, 350));
大功告成!
Vue.js中的解決方案
首先在公共函數文件中注冊debounce
export function debounce(func, delay) {
let timer
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
func.apply(this, args)
}, delay)
}
}
然后在需要使用的組件中引入debounce,並且在created生命周期內調用:
created() {
this.$watch('searchText', debounce((newSearchText) => {
this.getDatas(newSearchText)
}, 200))
}
大功告成!
引用
1. https://stackoverflow.com/questions/29771011/angularjs-watch-with-debounce
2. https://www.cnblogs.com/fsjohnhuang/p/4147810.html