每次使用input时,我的函数都会向服务器发送数据并得到响应,但是如果我想在“名称”字段中写东西-Thomas Edison,我将逐个字母地发送
我尝试放置setTimeout函数,如果用户仍在编写字符串,则不会发送任何内容,但我无法正常工作
@input="throttledSave"
throttledSave (e) {
let eva = e
let DELAY = 2000;
if(e.target.value){
return this.throttle(this.setDataFinalJSON, DELAY, eva);
}
},
throttle: function (callback, limit,eva) {
var wait = false;
var typingTimer;
return function (callback, limit,eva) {
clearTimeout(typingTimer)
if (!wait) {
callback(eva);
wait = true;
typingTimer = setTimeout(function () {
console.log('oh again')
wait = false;
}, limit);
}
}
}
每次都可以工作直到DELAY,我不知道为什么,也许clearTimeout不起作用,我被卡住了。我不知道为什么我这么快写一些文字,我得到了console.log('哦再次')
答案 0 :(得分:4)
您可以使用lodash防反跳(https://lodash.com/docs/4.17.15#debounce)方法做到这一点:
创建一个防反跳功能,将调用func延迟到之后 自上次反跳以来等待的毫秒数已过去 函数被调用。去抖动功能带有取消功能 取消延迟的函数调用的方法和刷新方法 立即调用它们。提供选项以指示是否func 应该在等待的前沿和/或后沿调用 暂停。将使用提供给的最后一个参数来调用func。 去抖动功能。后续对反跳功能的调用返回 最后一次func调用的结果。
_.debounce(func, [wait=0], [options={}])
示例:
methods: {
throttledMethod: _.debounce(() => {
console.log('I only get fired once every two seconds, max!')
}, 2000)
}
最好使用lodash的vue变体:https://www.npmjs.com/package/vue-lodash
答案 1 :(得分:3)
超时只会延迟每个输入事件(这样,每个输入事件都会在一段时间后导致请求),这不是您想要的。实现此目标的基本思想很简单:将最后一次输入事件的时间存储在模型中,然后在输入时仅在超时结束后才发送请求,例如:
data () {
return {
...
lastInputTime: null,
inputTimeout: 1000 // ms
}
},
...
methods: {
throttledSave (e) {
const attemptTime = new Date();
if(this.lastInputTime && attemptTime - this.lastInputTime > this.inputTimeout) {
// get value, send request etc
}
this.lastInputTime = attemptTime;
}
好吧,这就是所谓的反跳,dreijntjens提出了类似的建议,但使用的库可以修饰您的函数。
PS实际上,这样的修饰是一种更好的方法(除非您打算在运行时更改inputTimeout
),因为您不会因反跳而产生额外的杂物,从而使模型混乱;您可以制作自己的“装饰器”(严格来讲,装饰器不应该具有special syntax,而不是一个可以获取您的函数并返回修改后的函数的函数),如果您的项目没有摇摇欲坠库正确。像这样:
function debounce(func, timeout) {
let lastTime = null;
return function() {
const attemptTime = new Date();
if(lastTime && attemptTime - lastTime > timeout) {
func.apply(this, arguments);
}
lastTime = attemptTime;
}
}
lodash的实现更多sophisticated,因为它支持多个options。
答案 2 :(得分:1)
如何使用惰性输入模型修饰符?
VueJS prototype for delayed (lazy) input
Vue.prototype.lazyInput = function(e, delay) {
const self = this;
if (typeof delay == 'undefined') {
delay = 500;
}
const target = e.target;
if (self.lazyTimer) {
clearTimeout(self.lazyTimer);
self.lazyTimer = null;
}
self.lazyTimer = setTimeout(function(){
target.dispatchEvent(new Event('change'));
}, delay);
}
用法:
<input v-model.lazy="{variableName}" @input="lazyInput($event)">