Vuejs 2:去抖动不适用于手表选项
Vuejs 2: debounce not working on a watch option
当我在 VueJs 中对这个函数进行去抖动时,如果我提供毫秒数作为原语,它就可以正常工作。但是,如果我将它作为对道具的引用提供,它会忽略它。
这是道具的缩写版本:
props : {
debounce : {
type : Number,
default : 500
}
}
这是不起作用的监视选项:
watch : {
term : _.debounce(function () {
console.log('Debounced term: ' + this.term);
}, this.debounce)
}
这是一个有效的监视选项:
watch : {
term : _.debounce(function () {
console.log('Debounced term: ' + this.term);
}, 500)
}
怀疑是作用域问题,但不知如何解决。如果我按如下方式替换 watch 方法......:
watch : {
term : function () {
console.log(this.debounce);
}
}
...我在控制台中得到了正确的去抖动值 (500)。
new Vue({
el: '#term',
data: function() {
return {
term: 'Term',
debounce: 1000
}
},
watch: {
term : _.debounce(function () {
console.log('Debounced term: ' + this.term);
}, this.debounce)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script>
<div id="term">
<input v-model="term">
</div>
这里的主要问题是在定义去抖函数时使用 this.debounce
作为间隔。当时 _.debounce(...)
是 运行 (当组件正在编译时)函数还没有附加到 Vue,所以 this
是 而不是 Vue 和 this.debounce
将是未定义的。在这种情况下,您需要在创建组件实例后定义监视。 Vue 使您能够使用 $watch.
来做到这一点
我建议您将它添加到创建的生命周期处理程序中。
created(){
this.unwatch = this.$watch('term', _.debounce((newVal) => {
console.log('Debounced term: ' + this.term);
}, this.debounce))
},
beforeDestroy(){
this.unwatch()
}
注意上面的代码还调用了 unwatch
,它在组件被销毁之前。这通常由 Vue 为您处理,但由于代码是手动添加手表,因此代码还需要管理删除手表。当然,你需要添加 unwatch
作为数据 属性.
这是一个工作示例。
console.clear()
Vue.component("debounce",{
props : {
debounce : {
type : Number,
default : 500
}
},
template:`
<input type="text" v-model="term">
`,
data(){
return {
unwatch: null,
term: ""
}
},
created(){
this.unwatch = this.$watch('term', _.debounce((newVal) => {
console.log('Debounced term: ' + this.term);
}, this.debounce))
},
beforeDestroy(){
this.unwatch()
}
})
new Vue({
el: "#app"
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://unpkg.com/vue@2.4.2"></script>
<div id="app">
<debounce :debounce="250"></debounce>
</div>
@Bert 答案的另一种变体是在 created()
、
中构建观察者函数
// SO: Vuejs 2: debounce not working on a watch option
console.clear()
Vue.component("debounce",{
props : {
debounce : {
type : Number,
default : 500
}
},
template:`
<div>
<input type="text" v-model="term">
</div>
`,
data(){
return {
term: "",
debounceFn: null
}
},
created() {
this.debounceFn = _.debounce( () => {
console.log('Debounced term: ' + this.term);
}, this.debounce)
},
watch : {
term : function () {
this.debounceFn();
}
},
})
new Vue({
el: "#app"
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<div id="app">
<debounce :debounce="2000"></debounce>
</div>
示例 CodePen
debounced method
需要抽象化,因为我们需要在每次触发 watch
时调用相同的函数。如果我们将 debounced
方法放在 Vue
computed
或 watch
属性 中,它每次都会 更新 。
const debouncedGetData = _.debounce(getData, 1000);
function getData(val){
this.newFoo = val;
}
new Vue({
el: "#app",
template: `
<div>
<input v-model="foo" placeholder="Type something..." />
<pre>{{ newFoo }}</pre>
</div>
`,
data(){
return {
foo: '',
newFoo: ''
}
},
watch:{
foo(val, prevVal){
debouncedGetData.call(this, val);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="app"></div>
祝你好运...
当我在 VueJs 中对这个函数进行去抖动时,如果我提供毫秒数作为原语,它就可以正常工作。但是,如果我将它作为对道具的引用提供,它会忽略它。
这是道具的缩写版本:
props : {
debounce : {
type : Number,
default : 500
}
}
这是不起作用的监视选项:
watch : {
term : _.debounce(function () {
console.log('Debounced term: ' + this.term);
}, this.debounce)
}
这是一个有效的监视选项:
watch : {
term : _.debounce(function () {
console.log('Debounced term: ' + this.term);
}, 500)
}
怀疑是作用域问题,但不知如何解决。如果我按如下方式替换 watch 方法......:
watch : {
term : function () {
console.log(this.debounce);
}
}
...我在控制台中得到了正确的去抖动值 (500)。
new Vue({
el: '#term',
data: function() {
return {
term: 'Term',
debounce: 1000
}
},
watch: {
term : _.debounce(function () {
console.log('Debounced term: ' + this.term);
}, this.debounce)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script>
<div id="term">
<input v-model="term">
</div>
这里的主要问题是在定义去抖函数时使用 this.debounce
作为间隔。当时 _.debounce(...)
是 运行 (当组件正在编译时)函数还没有附加到 Vue,所以 this
是 而不是 Vue 和 this.debounce
将是未定义的。在这种情况下,您需要在创建组件实例后定义监视。 Vue 使您能够使用 $watch.
我建议您将它添加到创建的生命周期处理程序中。
created(){
this.unwatch = this.$watch('term', _.debounce((newVal) => {
console.log('Debounced term: ' + this.term);
}, this.debounce))
},
beforeDestroy(){
this.unwatch()
}
注意上面的代码还调用了 unwatch
,它在组件被销毁之前。这通常由 Vue 为您处理,但由于代码是手动添加手表,因此代码还需要管理删除手表。当然,你需要添加 unwatch
作为数据 属性.
这是一个工作示例。
console.clear()
Vue.component("debounce",{
props : {
debounce : {
type : Number,
default : 500
}
},
template:`
<input type="text" v-model="term">
`,
data(){
return {
unwatch: null,
term: ""
}
},
created(){
this.unwatch = this.$watch('term', _.debounce((newVal) => {
console.log('Debounced term: ' + this.term);
}, this.debounce))
},
beforeDestroy(){
this.unwatch()
}
})
new Vue({
el: "#app"
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://unpkg.com/vue@2.4.2"></script>
<div id="app">
<debounce :debounce="250"></debounce>
</div>
@Bert 答案的另一种变体是在 created()
、
// SO: Vuejs 2: debounce not working on a watch option
console.clear()
Vue.component("debounce",{
props : {
debounce : {
type : Number,
default : 500
}
},
template:`
<div>
<input type="text" v-model="term">
</div>
`,
data(){
return {
term: "",
debounceFn: null
}
},
created() {
this.debounceFn = _.debounce( () => {
console.log('Debounced term: ' + this.term);
}, this.debounce)
},
watch : {
term : function () {
this.debounceFn();
}
},
})
new Vue({
el: "#app"
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<div id="app">
<debounce :debounce="2000"></debounce>
</div>
示例 CodePen
debounced method
需要抽象化,因为我们需要在每次触发 watch
时调用相同的函数。如果我们将 debounced
方法放在 Vue
computed
或 watch
属性 中,它每次都会 更新 。
const debouncedGetData = _.debounce(getData, 1000);
function getData(val){
this.newFoo = val;
}
new Vue({
el: "#app",
template: `
<div>
<input v-model="foo" placeholder="Type something..." />
<pre>{{ newFoo }}</pre>
</div>
`,
data(){
return {
foo: '',
newFoo: ''
}
},
watch:{
foo(val, prevVal){
debouncedGetData.call(this, val);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="app"></div>
祝你好运...