title: Vue watch two linked input fields for user input only
body: <p>I have two input fields, the idea is that both can change the value of the other one.</p>
  <p>if a value of 1 - 200 is entered into the level field, Vue looks up the level and returns the amount of points for that level and enters them into the points field.</p>
  <p>But I also want the inverse to happen, so if a user enters an amount of points they have in the points field Vue looks up the points and returns the level associated with that amount of points.</p>
  <p>This works except Vue does a double calculation as it is watching both fields so if I enter 300 in the points field it correctly returns level 4 but then Vue detects the change in the level field and then changes the points to 250.</p>
  <p>I only want Vue to detect when the user changes the field instead of re-calculating after it changes the field.</p>
  <p>I hope this makes sense, it's a hard one to explain.</p>
  <p>A sample of the data returned from the axios request:-</p>
  <pre><code>[
      {&quot;level&quot;:1,&quot;points&quot;:0},
      {&quot;level&quot;:2,&quot;points&quot;:72},
      {&quot;level&quot;:3,&quot;points&quot;:175},
      {&quot;level&quot;:4,&quot;points&quot;:250},
      {&quot;level&quot;:5,&quot;points&quot;:401,}
  ]
  </code></pre>
  <p>a simplified vue component to demonstrate my working:-</p>
  <pre><code>&lt;template&gt;
      &lt;div&gt;
          &lt;div class=&quot;card-body&quot;&gt;
              &lt;form&gt;
                  &lt;div class=&quot;row&quot;&gt;
                      &lt;div class=&quot;col&quot;&gt;
                          &lt;div class=&quot;form-group&quot;&gt;
                              &lt;input type=&quot;text&quot; v-model=&quot;currentLevel&quot; class=&quot;form-control&quot;&gt;
                          &lt;/div&gt;
                          &lt;div class=&quot;form-group&quot;&gt;
                              &lt;input type=&quot;text&quot; v-model=&quot;currentPoints&quot; class=&quot;form-control&quot;&gt;
                          &lt;/div&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
              &lt;/form&gt;
          &lt;/div&gt;
      &lt;/div&gt;   
  &lt;/template&gt;
  
  &lt;script&gt;
      export default { 
          data() {
              return {
                  currentLevel: 1,
                  currentPoints: 0,
                  pointsTable: []
              }
          },
          mounted() {
              axios.get('/api/points').then(this.fetchPointsTable);
          },
          methods: {
              fetchPointsTable({data}) {
                  this.pointsTable = data;
              }
          },
          watch: {
              currentLevel: function() { 
                  const result = this.pointsTable.find( ({ level }) =&gt; level === parseInt(this.currentLevel) );
  
                  this.currentPoints = result.experience;
              },
              currentPoints: function() {
                  var levels = [];
                  var goal = this.currentXp;
  
                  var closest = this.xpTable.reduce(function(prev, curr) {
                      if (curr.points &lt;= goal) {
                          levels = curr.level;
                      }
                      return Math.max(levels);
                  });
  
                  this.currentLevel = closest;
              }
          }
      }
  &lt;/script&gt;
  </code></pre>