data(){ searchFr_el-input keydown">
当前位置:   article > 正文

el-input,使用keydown事件时,优化频繁触发后端==防抖在vue中使用_el-input keydown

el-input keydown

原型:

<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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

一开始我在页面中引入之后,在serarchhandle函数中直接调用;

import debounce feom "@/utils/debounce"
methods:{
	searchhandle(){
		//省略赋值操作
		......
		debounce(this.fetchData,800)
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

经过反复调试,发现页面一直没有触发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).....//获取数据做处理
},
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

这样就可以实现页面一进来就触发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)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/114590?site
推荐阅读
相关标签
  

闽ICP备14008679号