问题描述
有这样一个使用 Vue + ElementUI 制作的页面:
右上角是进行搜索的输入框,下面是所有的文件列表。要求在输入的时候搜索出与输入内容相同的文件名,考虑到性能影响,想要在输入事件方法中使用一个防抖函数:
<div class="search-input">
<el-autocomplete
v-model="searchValue"
:fetch-suggestions="querySearch"
:placeholder="$t('pleaseInput')"
:trigger-on-focus="false"
@input="handleInput"
@select="handleSelect"
@focus="showKeyboard"
@blur="handleBlur"
>
<el-button slot="append" icon="el-icon-search" @click="searchProject"></el-button>
</el-autocomplete>
在 input
事件方法 handleInput
中加入自己写的一个简单的防抖函数:
import { debounce } from '../../util/util.js';
methods: {
handleInput() {
debounce(function() {
// 没有输出
console.log('input');
}, 500);
}
}
// util.js
export function debounce(fn, delay) {
let t = null;
return function () {
if (t !== null) {
clearTimeout(t);
}
setTimeout(() => {
fn.call(this);
}, delay);
}
}
结果发现 handleInput
方法中的测试代码没有输出,防抖失效。
解决方法
考虑到是利用闭包封装的一个防抖函数,我们把 handleInput
不用 ES6 的方式改写一下:
methods: {
handleInput: function () {
debounce(function () {
console.log('input');
}, 500);
}
}
对比一下在原生 input 事件中会如何使用这个防抖函数:
inputElement.oninput = debounce(function () {
console.log('input'); // 'input'
}, 500);
有没有发现什么问题,在 Vue 中想要使用防抖应该直接使用,而不是在方法内部使用!
将 handleInput
函数修改如下即可:
methods: {
handleInput: debounce(function () {
console.log('input'); // 'input'
}, 500)
}