原型:

<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)
}
Logo

前往低代码交流专区

更多推荐