问题场景:
假设页面中有一个商品列表,列表上方有一个输入框用来过滤商品,当用户每次输入时,自动过滤商品。当用户连续输入时,譬如:用户一次性输入“红富士苹果”,这时会程序自动过滤五次,分别是:“红”、“红富”、“红富士”、“红富士苹”和“红富士苹果”,但其实我们只需要按“红富士苹果”过滤一次即可,其余四次都是不必要的,如果数据量大还会造成卡顿。
需求分析:
判断用户是否连续输入,需要记录上一次输入时间和当前输入时间,如果【当前输入时间】 - 【上一次输入时间】 < 200(单位毫秒,200是我自己定的),则判断用户为连续输入,不进行过滤。
发现问题:
如果用户一直连续输入,即直到停止输入时,一直都是连续输入,那么怎么判断用户是否停止输入?
解决问题:
采用定时器,通过定时器判断用户是否停止输入,即再过200毫秒(定时器间隔)时,判断【当前时间】- 【上一次输入时间】> 200,则判断用户停止输入,此时应该执行相应的过滤方法。
代码(vue2+elementui):
<template>
<div>
<div class="filter-wrapper">
<div class="filter-member">
<label for="tradeName">商品名称:</label>
<el-input placeholder="商品名称" id="tradeName" v-model="tradeName" size="mini"></el-input>
</div>
</div>
<div>
<el-table :data="filterGoods" style="width: 100%" size="mini" stripe>
<el-table-column prop="tradeName" label="商品名称"></el-table-column>
<el-table-column prop="category" label="类别"></el-table-column>
<el-table-column prop="price" label="价格"></el-table-column>
</el-table>
</div>
</div>
</template>
<script>
export default {
data() {
return {
goodsList: [],//所有商品列表
filterGoods: [],//过滤后的商品列表
tradeName: '',//商品名称
inputTimestamp: 0,//上一次输入时间
timeInterval: -1,//定时器
};
},
methods: {
//过滤方法
filter() {
clearInterval(this.timeInterval);//清空定时器
this.filterGoods= this.goodsList.filter(item => {
return item.tradeName && item.tradeName .indexOf(this.tradeName ) != -1;
});
},
inputFilter() {
//当前时间 - 上一次输入时间 < 200 则为连续输入
if (Date.now() - this.inputTimestamp < 200) {
//上一次输入时间赋值为当前时间
this.inputTimestamp = Date.now();
return;
}
else {
this.inputTimestamp = Date.now();
//输入间隔大于200 则判断连续输入终止,执行过滤方法
this.filter();
}
}
},
async created() {
//调用api获取所有商品列表
this.filterGoods= this.goodsList= await this.$api.oraApi.GetGoodsList();
},
watch: {
tradeName() {
//每次输入时清空定时器
clearInterval(this.timeInterval);
this.timeInterval = setInterval(() => {
this.inputFilter();
}, 200);
}
}
};
</script>