一、需求:下拉框支持遠程搜索,根據用戶輸入字符,調接口獲取數據渲染到下拉列表上,供用戶選擇。
二、為什么要做 防抖控制?在做遠程搜索時,如果每輸入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