el-input,使用keydown事件时,优化频繁触发后端==防抖在vue中使用
原型:<el-inputstyle="width:200px"size="small"v-model="searchKeyword"type="text"@keydown.native="searchhandle"placeholder="搜索"></el-input>data(){searchFr
原型:
<el-input
style="width:200px"
size="small"
v-model="searchKeyword"
type="text"
@keydown.native="searchhandle"
placeholder="搜索"
></el-input>
data(){
searchFrom:{}
}
methods:{
fechData(){
Api(this.searchFrom).....//获取数据做处理
},
searchhandle(event){
//将searchfrom重新赋值去触发获取表格数据的函数
this.fechData();
}
}
1.使用keypress去触发时,当用户删除掉多余的输入时,只能按回车才能触发这个keypress,所以用户想要按下就触发则使用keydown
2.监听根元素的原生事件,需要使用.native修饰符,不加则不会生效
分析:
1.上述代码是可以实现用户输入一定内容后去请求后端,这种操作是过于频繁的触发接口,导致页面性能不好。
2.为了缓解这个频繁的触发,可以考虑使用防抖和节流,
防抖是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
节流是指连续触发事件但是在 n 秒中只执行一次函数。
这里我们采用防抖的非立即执行版,也就是过了n秒之后调用。
//debounce.js
function debounce(callback, ms) {
let timeout
return function() {
const context = this
const args = arguments
if (timeout) clearTimeout(timeout)
timeout = setTimeout(() => {
callback.apply(context, args)
}, ms)
}
}
export default debounce
一开始我在页面中引入之后,在serarchhandle函数中直接调用;
import debounce feom "@/utils/debounce"
methods:{
searchhandle(){
//省略赋值操作
......
debounce(this.fetchData,800)
}
}
经过反复调试,发现页面一直没有触发fetchData()函数。
发现:
1.debounce传入一个函数和一个延迟时间。因为keydown事件,用户每按下一次就会触发searchhandle事件,每次触发searchhandle事件都会去触发debounce这个函数。
2.每次触发debounce这个函数,就表明没有形成闭包。因为每次一进来就会命名一个timer变量,并且每次进来都会返回一个函数并且没有执行。
3.防抖应该是debounce这个函数只执行一次,后面每次操作应该是执行的是return里面的函数,形成里闭包,实现防抖。
所以应该写成这样
<el-input
style="width:200px"
size="small"
v-model="searchKeyword"
type="text"
id="searchInput"
placeholder="搜索"
></el-input>
data(){
searchFrom:{}
}
imort debounce from "@/utils/debounce"
mounted(){
let _this=this;
document.getElenmentById("searchInput").addEventListener("keydown",debounce(_this.fetchData(),800))
},
beforDestory(){
window.removeEventListener("keydown",_this.fetchData(),800)
},
methods:{
fechData(){
Api(this.searchFrom).....//获取数据做处理
},
}
这样就可以实现页面一进来就触发debounce这个函数(可以在防抖的页面打印传入的函数看看为什么会执行return),后面每次的操作都走的return里面的流程.
经调试上面代码有误
注意:我是给input DOM添加的keydow事件,如果通过window去移除是移除不掉的,必须是同一目标对象,另外addEventListener和removeEventListener需要事件名一致,事件处理函数一致,传入相同的布尔值(true代表捕获阶段,false代表冒泡阶段),由于debounce返回的都是函数,但是两个函数是不一致的,所以移除的时候要保证一致。)
‘
所以应该写成:
data(){
return {
searchDom:null,
searchHandle:null
}
},
mounted(){
this.searchDom=document.getElementById("searchInput");//为了让beforDestory阶段拿到DOM对象
this.searchHandle=debounce(this.fetchData().800);//为了移除的时候保证返回的函数是相同的
let _this=this;
this.searchDom.addEventListener(_this.searchHandle)
},
beforDestory(){
let _this=this;
this.searchDom.removeEventListener(_this.searchHandle)
}
更多推荐
所有评论(0)