Vue.js 和 debounce (lodash/underscore) 兼容吗?
Are Vue.js and debounce (lodash/underscore) compatible?
在 to my 之后,我想知道 vue.js 和 lodash
/underscore
是否兼容此功能。答案中的代码
var app = new Vue({
el: '#root',
data: {
message: ''
},
methods: {
len: _.debounce(
function() {
return this.message.length
},
150 // time
)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.6/vue.js"></script>
<script src="https://unpkg.com/underscore@1.8.3"></script> <!-- undescore import -->
<div id="root">
<input v-model="message">Length: <span>{{ len() }}</span>
</div>
我的函数在连续输入的时候确实一直在执行,但是等了一段时间activity终于执行的时候,function()
的输入好像是错误的[=31] =]
上面代码启动后的实际例子:
- 快速字符序列,然后没有activity:
- 添加了一个额外的字符 (
b
),没有 activity -- 长度已更新(但错误,见下文)
- 使用 Backspace 快速擦除所有字符:
- 添加一个字符:
看起来函数是 运行 在 message
的最后一个值上。
会不会是 _.debounce
在 vue.js data
实际更新为 <input>
值之前处理了它?
备注:
- 使用
lodash
和 underscore
进行了测试,结果相同(对于 debounce
和 throttle
函数)。
- 我还在 JSFiddle 上测试了它,以防对 SO 代码段造成一些干扰
为什么会发生这种情况是因为 Vue 仅在方法中使用的 vue 变量发生变化时才调用 methods,如果 vue 变量没有变化,则不会触发这些方法。
同样在这种情况下,一旦我们停止输入,它将继续显示上次调用方法的输出,并且只会在您再次输入时再次显示。
如果您不想在所有输入上调用一个函数,另一种方法是调用方法 on blur 事件,这样只有当焦点离开输入字段时才会调用方法,如下所示:
var app = new Vue({
el: '#root',
data: {
message: '',
messageLen: 0
},
methods: {
updatateLen:
function() {
this.messageLen = this.message.length
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.6/vue.js"></script>
<script src="https://unpkg.com/underscore@1.8.3"></script> <!-- undescore import -->
<div id="root">
<input v-model="message" v-on:blur="updatateLen">Length: <span>{{ messageLen }}</span>
</div>
这是@saurabh 版本的改进版本。
var app = new Vue({
el: '#root',
data: {
message: '',
messageLen: 0
},
methods: {
updateLen: _.debounce(
function() {
this.messageLen = this.message.length
}, 300)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.6/vue.js"></script>
<script src="https://unpkg.com/underscore@1.8.3"></script> <!-- undescore import -->
<div id="root">
<input v-model="message" v-on:keyup="updateLen">Length: <span>{{ messageLen }}</span>
</div>
在 lodash
/underscore
是否兼容此功能。答案中的代码
var app = new Vue({
el: '#root',
data: {
message: ''
},
methods: {
len: _.debounce(
function() {
return this.message.length
},
150 // time
)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.6/vue.js"></script>
<script src="https://unpkg.com/underscore@1.8.3"></script> <!-- undescore import -->
<div id="root">
<input v-model="message">Length: <span>{{ len() }}</span>
</div>
我的函数在连续输入的时候确实一直在执行,但是等了一段时间activity终于执行的时候,function()
的输入好像是错误的[=31] =]
上面代码启动后的实际例子:
- 快速字符序列,然后没有activity:
- 添加了一个额外的字符 (
b
),没有 activity -- 长度已更新(但错误,见下文)
- 使用 Backspace 快速擦除所有字符:
- 添加一个字符:
看起来函数是 运行 在 message
的最后一个值上。
会不会是 _.debounce
在 vue.js data
实际更新为 <input>
值之前处理了它?
备注:
- 使用
lodash
和underscore
进行了测试,结果相同(对于debounce
和throttle
函数)。 - 我还在 JSFiddle 上测试了它,以防对 SO 代码段造成一些干扰
为什么会发生这种情况是因为 Vue 仅在方法中使用的 vue 变量发生变化时才调用 methods,如果 vue 变量没有变化,则不会触发这些方法。
同样在这种情况下,一旦我们停止输入,它将继续显示上次调用方法的输出,并且只会在您再次输入时再次显示。
如果您不想在所有输入上调用一个函数,另一种方法是调用方法 on blur 事件,这样只有当焦点离开输入字段时才会调用方法,如下所示:
var app = new Vue({
el: '#root',
data: {
message: '',
messageLen: 0
},
methods: {
updatateLen:
function() {
this.messageLen = this.message.length
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.6/vue.js"></script>
<script src="https://unpkg.com/underscore@1.8.3"></script> <!-- undescore import -->
<div id="root">
<input v-model="message" v-on:blur="updatateLen">Length: <span>{{ messageLen }}</span>
</div>
这是@saurabh 版本的改进版本。
var app = new Vue({
el: '#root',
data: {
message: '',
messageLen: 0
},
methods: {
updateLen: _.debounce(
function() {
this.messageLen = this.message.length
}, 300)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.6/vue.js"></script>
<script src="https://unpkg.com/underscore@1.8.3"></script> <!-- undescore import -->
<div id="root">
<input v-model="message" v-on:keyup="updateLen">Length: <span>{{ messageLen }}</span>
</div>