1、vue中實時監(jiān)聽input值的變化,停止輸入300ms后去請求,而不是時時請求數(shù)據(jù)
2、解決異步請求可能會發(fā)生先請求后返回問題,導(dǎo)致結(jié)果列表不是預(yù)料展示的效果
一、問題
做搜索功能時,監(jiān)聽input的value值變化實時請求數(shù)據(jù),每增加一個字符,就發(fā)送一次請求。例如輸入12345,會監(jiān)聽到5次變化1 12 123 1234 12345,導(dǎo)致連續(xù)請求5次。這是沒必要的,增加服務(wù)器負(fù)擔(dān),可能出現(xiàn)卡頓的情況。
甚至,一定概率下會發(fā)生請求返回順序問題,當(dāng)輸入速度很快時,連續(xù)發(fā)請求,服務(wù)器可能先返回12345請求的結(jié)果,然后再返回12請求的結(jié)果,導(dǎo)致最后頁面上顯示的結(jié)果是12請求到的結(jié)果列表,而不是想要搜索的12345的結(jié)果。一定程度上降低這種情況。
二、想法
不希望input框中值一改變,就馬上去請求數(shù)據(jù),而是在指定間隔內(nèi)沒有輸入時,才會執(zhí)行函數(shù)。如果停止輸入但是在指定間隔內(nèi)又輸入,會重新觸發(fā)計時。這就是函數(shù)防抖。
實時監(jiān)聽input值的變化,輸入一個字符,300ms后再去獲取input中的輸入值。
三、關(guān)鍵代碼
<input ref="searchInput" v-model="inputVal" type="text" placeholder="搜索目的地" maxlength="20"/>
data() {
return {
inputVal: '',
timeout: null,
}
}
watch: {
inputVal(curVal, oldVal) {
// 實現(xiàn)input連續(xù)輸入,只發(fā)一次請求
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.getListPOI(curVal);
}, 300);
}
}
四、再優(yōu)化,解決異步請求可能發(fā)生先請求后返回問題,導(dǎo)致結(jié)果列表不是預(yù)料展示的效果
假如300ms的延遲,服務(wù)器還是可能存在先發(fā)送的請求后返回。避免先請求后返回問題,確保以當(dāng)前輸入的值12345為參數(shù)給結(jié)果表賦值,可以在請求里做判斷。當(dāng)請求返回結(jié)果時,判斷請求的參數(shù)inputVal和當(dāng)前輸入框的值this.inputVal相等,才進(jìn)行相關(guān)操作:if (this.inputVal === inputVal) {...}
methods:{
/**
* poi模糊搜索列表
*/
async getListPOI(inputVal) {
if (inputVal === '') {
return false;
}
this.searchPoi = [];
this.divLoading = true;
if (!navigator.onLine) { // 沒有網(wǎng)絡(luò)
this.onLine = false;
this.divLoading = false;
return false;
} else {
this.onLine = true;
}
try {
const res = await getListPOI({
"buildId": this.$store.state.showBuildId,
"coor": 1,
"floorId": this.$store.state.showFloorId,
"latitude": this.$store.state.userCurLoc[1] || 0,
"longitude": this.$store.state.userCurLoc[0] || 0,
"name": inputVal,
"pageNum": 1,
"pageSize": 30
});
if (this.inputVal === inputVal) { // 關(guān)鍵代碼 避免先請求后返回問題,確保給列表賦值是以當(dāng)前輸入的值為參數(shù)的
if (res.code === 0 && res.data) {
let data = res.data;
if (data.length === 0) {
this.hasResult = false;// 沒有結(jié)果
this.searchPoi = [];
} else { // 有結(jié)果
this.hasResult = true;
this.searchPoi = data;
}
} else {
this.searchPoi = [];
console.log("請檢查/poi/list/POI接口返回的數(shù)據(jù)格式");
}
this.divLoading = false;
}
} catch (err) {
this.divLoading = false;
console.log("poi模糊搜索列表接口請求失敗", err);
}
}
}
五、效果圖

看到一篇寫函數(shù)防抖的文章不錯,推薦一下:https://blog.csdn.net/duola8789/article/details/78871789
這邊看到的有個
在React、Vue和小程序中使用函數(shù)節(jié)流和函數(shù)防抖
地址:https://blog.csdn.net/qq_37860930/article/details/83545473
謝謝作者的分享~~
作者:吖蛋黃
鏈接:http://www.itdecent.cn/p/3d23efcefb38
來源:簡書
簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。