Rai*_*ška 8 vue.js quasar debounce
我有一个Vue组件,它使用多个子组件.在这些子组件上,我有一个观察数据变化并处理这些变化的观察者.我想为此实施去抖动.
watch: {
data: {
handler: function () {
this.processData()
},
deep: true
}
},
methods: {
processData: debounce(function () {
console.log(this.id)
}, 250),
Run Code Online (Sandbox Code Playgroud)
问题是debounce有效,所以它只在最后一个子组件上执行.
我找到了一个debounce函数的解决方案,可以接受额外的id debounceWithId
但问题是,如果我指定此函数如下:
methods: {
processData: debounceWithId(function () {
console.log(this.id)
}, 250, this.id),
Run Code Online (Sandbox Code Playgroud)
最后一个this.id未定义.
在多个组件中使用去抖动的正确方法是什么,因此该函数会在每个组件上单独触发?
Ber*_*ert 13
首先让我添加一个复制您正在描述的问题的示例.
console.clear()
function debounce(func, wait, immediate) {
var timeout;
return function() {
console.log("Called from component ", this._uid)
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
Vue.component("doesntwork",{
props:["value"],
template:`<div>Component #{{_uid}} Value: {{innerValue}}</div>`,
data(){
return {
innerValue: this.value
}
},
watch:{
value(newVal){
this.processData(newVal)
}
},
methods:{
processData: debounce(function(newVal){
this.innerValue = newVal
}, 1000)
},
})
new Vue({
el: "#app",
data:{
parentValue: null,
}
})Run Code Online (Sandbox Code Playgroud)
<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">
Type some text. Wait one second. Only the *last* component is updated.<br>
<input type="text" v-model="parentValue">
<doesntwork :value="parentValue"></doesntwork>
<doesntwork :value="parentValue"></doesntwork>
<doesntwork :value="parentValue"></doesntwork>
</div>Run Code Online (Sandbox Code Playgroud)
基本上这里发生的是debounced函数是在编译组件时创建的,并且组件的每个实例共享相同的去抖动函数.每个的上下文this都会有所不同,但它的功能是相同的.我console.log在生成的debounced函数中添加了一个,以便您可以看到所有三个组件共享相同的功能.在这种情况下,该功能正在做它的设计目的; 它会在经过一段时间后执行一次,这就是为什么只更新最后一个组件的原因.
要绕过这种行为,您需要为每个组件提供独特的去抖功能.这有两种方法可以做到这一点.
方法一
您可以使用占位符的数量初始化processData方法.
methods: {
processData(){}
}
Run Code Online (Sandbox Code Playgroud)
然后,在创建的生命周期事件中,将processData方法更改为debounced方法.
created(){
this.processData = debounce(function(){
console.log(this.id)
}, 250)
}
Run Code Online (Sandbox Code Playgroud)
这将为每个组件提供独特的去抖功能,并且应该处理只有最后一个组件正常工作的问题.
以下是从上面的示例修改的示例.
console.clear()
Vue.component("works",{
props:["value"],
template:`<div>Component #{{_uid}} Value: {{innerValue}}</div>`,
data(){
return {
innerValue: this.value,
}
},
watch:{
value(newVal){
this.processData(newVal)
}
},
methods:{
processData() {}
},
created(){
this.processData = _.debounce(function(newVal){
this.innerValue = newVal
}, 1000)
}
})
new Vue({
el: "#app",
data:{
parentValue: null,
}
})Run Code Online (Sandbox Code Playgroud)
<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">
Type some text. Wait one second. <em>All</em> components are updated.<br>
<input type="text" v-model="parentValue">
<works :value="parentValue"></works>
<works :value="parentValue"></works>
<works :value="parentValue"></works>
</div>Run Code Online (Sandbox Code Playgroud)
方法二
感谢@RoyJ的建议.您可以在中定义processData方法data.通常你不这样做,因为你不经常需要函数的多个副本,这就是methods组件定义的部分存在的原因,但是在这种情况下,你需要为每个组件提供一个独特的函数,你可以定义数据函数中的方法,因为为组件的每个实例调用了数据函数.
data(){
return {
innerValue: this.value,
processData: _.debounce(function(newVal){
this.innerValue = newVal
}, 1000)
}
},
Run Code Online (Sandbox Code Playgroud)
以下是使用该方法的示例.
console.clear()
Vue.component("works",{
props:["value"],
template:`<div>Component #{{_uid}} Value: {{innerValue}}</div>`,
data(){
return {
innerValue: this.value,
processData: _.debounce(function(newVal){
this.innerValue = newVal
}, 1000)
}
},
watch:{
value(newVal){
this.processData(newVal)
}
},
})
new Vue({
el: "#app",
data:{
parentValue: null,
}
})Run Code Online (Sandbox Code Playgroud)
<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">
Type some text. Wait one second. <em>All</em> components are updated.<br>
<input type="text" v-model="parentValue">
<works :value="parentValue"></works>
<works :value="parentValue"></works>
<works :value="parentValue"></works>
</div>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1245 次 |
| 最近记录: |