Vuejs:检测计算值的更改事件

Don*_*nie 5 javascript vue.js

目标

我只想检测 的更改事件searchTerms

问题

目前,观察者在每次按键时都会触发,但我不想要那么多事件。

上下文(查看小提琴

<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>
Run Code Online (Sandbox Code Playgroud)

ase*_*hle 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');
    }
  }
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)