目标
我想检测仅更改事件searchTerms
。
问题
观察者目前在每个按键上触发,但我不想要那么多事件。
上下文(View Fiddle)
<template>
<div id="app">
<table class="table">
<tr>
<td><label>Name</label></td>
<td><input class="form-control" v-model="customer.name" autofocus></td>
</tr>
<tr>
<td><label>Short Code</label></td>
<td><input class="form-control" v-model="customer.shortCode"></td>
</tr>
<tr>
<td><label>Address</label></td>
<td><input class="form-control" v-model="customer.address"></td>
</tr>
<tr>
<td><label>Caller</label></td>
<td><input class="form-control" v-model="customer.caller"></td>
</tr>
<tr>
<td><label>Phone</label></td>
<td><input class="form-control" v-model="customer.phone"></td>
</tr>
</table>
<div class="models">
<pre><strong>customer:</strong> {{ customer | json }}</pre>
<pre><strong>searchTerms:</strong> {{ searchTerms | json }}</pre>
</div>
</div>
</template>
<script>
new Vue({
el: '#app',
data: {
customer: {
name: 'Donnie',
phone: '',
caller: '',
address: '',
shortCode: 'DO'
}
},
computed: {
searchTerms: function() {
let terms = {};
_.forOwn(this.customer, (value, key) => {
if (value.length >= 3) {
terms[key] = value;
}
});
return terms;
}
},
watch: {
'searchTerms': function() {
if (_.isEmpty(this.searchTerms)) {
return;
}
alert('searchTerms Changed');
}
}
});
</script>
答案 0 :(得分:0)
您可以debounce使用lodash,由here提供。它创建一个去抖动函数,该函数延迟调用func直到自上次调用去抖动函数后经过等待毫秒之后。 Debouncing用于限制我们执行Ajax请求和其他昂贵操作的频率
您可以通过单独的方法添加您不想调用的内容,并在_.debounce
内调用这些操作,如下所示:
methods: {
// This is where the debounce actually belongs.
expensiveOperation: _.debounce(function () {
this.isCalculating = true
setTimeout(function () {
alert('searchTerms Changed');
}.bind(this), 1000)
}, 500)
}
您可以根据要求更改setTimeout
中的延迟。
查找更新的小提琴{{3}}。
答案 1 :(得分:0)
计算属性searchTerms
每次运行时都会创建一个新对象。这意味着对searchTerms
的引用发生了变化,导致观察者触发。
如果其中一个值发生了变化,您只希望触发观察者。最简单的方法是观察searchTerms
的字符串化版本,而不是对象。
这是更新的小提琴:https://jsfiddle.net/qLzu0seq/5/
以下是代码作为代码段(将代码保留在stackoverflow中,而不是外部站点,这很好):
new Vue({
el: '#app',
data: {
customer: {
name: 'Donnie',
phone: '',
caller: '',
address: '',
shortCode: 'DO'
}
},
computed: {
searchTerms: function() {
let terms = {};
_.forOwn(this.customer, (value, key) => {
if (value.length >= 3) {
terms[key] = value;
}
});
return terms;
},
searchTermsStringified: function() {
return JSON.stringify(this.searchTerms);
}
},
watch: {
'searchTermsStringified': function() {
if (_.isEmpty(this.searchTerms)) {
return;
}
alert('searchTerms Changed');
}
}
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.4/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.js"></script>
<div id="app">
<table class="table">
<tr>
<td><label>Name</label></td>
<td><input class="form-control" v-model="customer.name" autofocus></td>
</tr>
<tr>
<td><label>Short Code</label></td>
<td><input class="form-control" v-model="customer.shortCode"></td>
</tr>
<tr>
<td><label>Address</label></td>
<td><input class="form-control" v-model="customer.address"></td>
</tr>
<tr>
<td><label>Caller</label></td>
<td><input class="form-control" v-model="customer.caller"></td>
</tr>
<tr>
<td><label>Phone</label></td>
<td><input class="form-control" v-model="customer.phone"></td>
</tr>
</table>
<div class="models">
<pre><strong>customer:</strong> {{ JSON.stringify(customer,null,2) }}</pre>
<pre><strong>searchTerms:</strong> {{ JSON.stringify(searchTerms,null,2) }}</pre>
</div>
</div>
&#13;
答案 2 :(得分:0)
您可以直接在计算属性函数中检查值是否已更改
由于要生成对象,因此需要使用_.isEqual
方法来测试值是否已更改。您还需要存储以前的值进行比较。
new Vue({
el: '#app',
data: {
customer: {
name: 'Donnie',
phone: '',
caller: '',
address: '',
shortCode: 'DO'
},
previousSearchTerms: null
},
computed: {
searchTerms: function() {
let terms = {};
_.forOwn(this.customer, (value, key) => {
if (value.length >= 3) {
terms[key] = value;
}
});
if (this.previousSearchTerms && !_.isEqual(terms, this.previousSearchTerms)) {
alert('I was changed !');
}
this.previousSearchTerms = terms;
return terms;
}
}
});
label { font-weight: bold; }
.models {
background: #eee;
margin: 1rem;
padding: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.2/lodash.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.5/css/bootstrap.min.css" />
<div id="app">
<table class="table">
<tr>
<td><label>Name</label></td>
<td><input class="form-control" v-model="customer.name" autofocus></td>
</tr>
<tr>
<td><label>Short Code</label></td>
<td><input class="form-control" v-model="customer.shortCode"></td>
</tr>
<tr>
<td><label>Address</label></td>
<td><input class="form-control" v-model="customer.address"></td>
</tr>
<tr>
<td><label>Caller</label></td>
<td><input class="form-control" v-model="customer.caller"></td>
</tr>
<tr>
<td><label>Phone</label></td>
<td><input class="form-control" v-model="customer.phone"></td>
</tr>
</table>
<div class="models">
<pre><strong>customer:</strong> {{ customer | json }}</pre>
<pre><strong>searchTerms:</strong> {{ searchTerms | json }}</pre>
</div>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/1.0.12/vue.js"></script>