一、需求:下拉框支持远程搜索,根据用户输入字符,调接口获取数据渲染到下拉列表上,供用户选择。
二、为什么要做 防抖控制?在做远程搜索时,如果每输入1个字就调用1次接口,就会频繁地掉接口请求数据,假设我们的查询是"12345",不考虑用户输入错误的情况,至少会请求5次。很明显这样频繁地查询数据库是不合理地,而且当数据过多的时候这里就会卡顿,造成性能浪费,因此需要防抖,即 设置多少毫秒内不管用户输入多少个字符,最终只根据最后一次输入完毕后输入框的字符去后台请求匹配数据。
debounce防抖也属于前端性能优化地一部分。
三、使用
1、安装loadsh依赖包(附上lodash的官方文档)
npm install –save lodash
2、在vue文件种引入(局部)
import _ from ‘lodash‘
3、实现
<el-select
v-model="value"
placeholder="请选择"
@change="selectChange"
filterable
remote
clearable
:remote-method="remoteMethod"
:loading="remoteLoading"
no-match-text="没有匹配到数据"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
//data层
export default {
data() {
return {
remoteLoading:false,
keyWord:"", //远程搜索条件
options:[], //下拉列表展示数据
value: ‘‘, //select绑定所选值
allOptions:[], //全部数据
}
},
computed: {
queryParams() {
return {
pageSize:-1, //-1,查询所有数据
pageNumber:1,
schoolKey:this.keyWord
}
},
},
methods:{
remoteMethod(searchKey) { //输入值发生变化时的回调函数
if(searchKey !== "") {
this.remoteLoading = true
this.keyWord=searchKey
this.getRemote()
} else{
this.options = this.allOptions
}
},
getRemote: _.debounce(function(){
//防抖,这里设置300毫秒请求一次后台
this.getList(this.queryParams)
},300),
async getList(params) {
//请求接口
this.remoteLoading = false
const [err,res] = await getInterfaceList(params)
const data = res.datas || []
this.options= data.map(item => {
return {
value:item.value,
label:item.label
}
})
},
}
}
注意,这里的防抖不是针对remoteMethod() 方法,而是remoteMethod() 方法里面调用的那个远程搜索方法(getRemote方法)。
4、结果:用户每次输入一个字符都会触发remoteMethod() 方法,remoteMethod() 会调用getRemote() 方法,这里通过对getRemote()设置防抖,达到不管用户输入数据怎么变化 300ms内只去后台请求一次。
引申:
- 节流:将一个函数的调用频率限制在一定阈值内,例如
1s
内一个函数不能被调用两次。(throttle) - 防抖:当调用函数
n
秒后,才会执行该动作,若在这n
秒内又调用该函数则将取消前一次并重新计算执行时间,比节流的流量控制效果更佳明显(debounce)。举个简单的例子,我们要根据用户输入做suggest,每当用户按下键盘的时候都可以取消前一次,并且只关心最后一次输入的时间就行了。
两者都是函数调用频率的控制器。
1、原理:
函数节流的核心是,让一个函数不要执行得太频繁,减少一些过快的调用来节流。也就是在一段固定的时间内只触发一次回调函数,即便在这段时间内某个事件多次被触发也只触发回调一次。
防抖的原理是在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。也就是说事件来了,先setTimeout定个时,n秒后再去触发回调函数。它和节流的不同在于如果某段时间内事件以间隔小于n秒的频率执行,那么这段时间回调只会触发一次。节流则是按照200ms或者300ms定时触发,而不仅仅是一次。
2、应用场景:
防抖的应用场景是连续的事件响应我们只触发一次回调,比如下面的场景:
- resize/scroll 触发统计事件
- 文本输入验证,不用用户输一个文字调用一次ajax请求,随着用户的输入验证一次就可以
节流是个很公平的函数,隔一段时间就来触发回调,比如下面的场景:
- DOM 元素的拖拽功能实现(mousemove)
- 计算鼠标移动的距离(mousemove)
- 搜索联想(keyup)
3、为什么这些适合节流而不是防抖呢?
我们想想哈,按照防抖的概念如果n秒内用户连续不断触发事件,则防抖会在用户结束操作结束后触发回调。 那对于拖动来说,我拖了半天没啥反应,一松手等n秒,啪。元素蹦过来了,这还是拖动吗?这是跳动吧,2333;
引:
https://segmentfault.com/a/1190000012102372?utm_source=tuicool&utm_medium=referral