目标

我只想检测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>

最佳答案

计算的属性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');
    }
  }
});
<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>

10-06 15:29