Vue $watch() Method


Example

Using the $watch() method to create a watcher that writes a new message every time the 'value' data property changes.

mounted() {
  this.$watch('value', function() {
    this.results.push('$watch() method')
  })
}
Run Example »

See more examples below.


Definition and Usage

The $watch() method is used to create watchers.

The $watch() method returns a stop function we can use to stop the watcher. (See Example 4)

A watcher is set up to watch for changes in a value (first argument), and to do something when a change occurs (second argument). It is also possible define other properties for the watcher (third argument).

Argument Description
watch source Required. The first argument is the watch source. This can be a component property name string (Example above), a simple dot-delimited path string (Example 5), or a function (Example 6).
callback function Required. The second argument is a callback function that runs when there is a change in the watch source. The callback function can be set up to receive the new and old value of the watch source as arguments (See Example 1).
options object Optional. Here we can specify the options deep, immediate, flush, and onTrigger/onTrack.

deep: Default value is 'false'. If the watcher is deep, it also reacts to changes further down in the property the watcher is set up to watch. (See Example 2)

immediate: Default value is 'false'. Triggers the watcher immediately after it is created. The old value will be 'undefined' the first time the watcher is triggered when 'immediate' is set to 'true'. (See Example 3)

flush: Default value is 'pre'. Specify when to run the callback function relative to when the component is rendered. Possible values are 'pre', 'post' and 'sync'. Use this flush option with caution.

onTrigger/onTrack: Used for debugging. Only works in development mode.

Note: Watchers can also be created using the watch option.


More Examples

Example 1

Using the $watch() method to write a new message with the old and new values every time the 'value' data property changes.

<template>
  <h2>Example $watch() Method</h2>
  <p>Drag the slider to change the value so that the $watch() method is triggered. The callback function writes a message with the new and old values.</p>
  <div>
    <p><input type="range" min="0" max="10" v-model="value"> Current value: {{ value }}</p>
    <ol>
      <li v-for="x in results">{{ x }}</li>
    </ol>
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: 4,
      results: []
    };
  },
  mounted() {
    this.$watch('value', function(newVal, oldVal) {
      this.results.push('Old value:'+oldVal+', new value: '+newVal)
    })
  }
};
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
}
</style>
Run Example »

Example 2

Using the $watch() method with the deep watch option set to 'true'. The watcher can now detect changes further inside the 'value' object.

<template>
  <h2>Example $watch() Method</h2>
  <p>Register an extra hobby for Stuart. The hobbies are stored in an array inside the 'value' object. The $watch() method
    is triggered because the 'deep' option is set to 'true' so that the watcher also detects changes further inside the
    object.</p>
  <div>
    <p>Register an extra hobby for Stuart:</p>
    <p><input type="text" ref="inpText"></p>
    <button v-on:click="regHobby">Register</button>
    <ol>
      <li v-for="x in watchMessages">{{ x }}</li>
    </ol>
  </div>
  <p>Current 'value' object:</p>
  <pre>{{ this.value }}</pre>
</template>

<script>
export default {
  data() {
    return {
      value: {
        owner: 'Stuart',
        address: 'Faraway Lane',
        hobbies: ['Bird watching', 'Trail running']
      },
      watchMessages: []
    };
  },
  methods: {
    regHobby() {
      this.value.hobbies.push(this.$refs.inpText.value);
      this.$refs.inpText.value = null;
      this.$refs.inpText.focus();
    }
  },
  mounted() {
    this.$watch('value', function () {
      this.watchMessages.push('watcher triggered')
    }, {
      deep: true
    });
  }
};
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
}

li {
  background-color: lightgreen;
}</style>
Run Example »

Example 3

Using the $watch() method with the immediate watch option set to 'true'. The watcher is now also triggered right after it is created.

<template>
  <h2>Example $watch() Method</h2>
  <p>With the 'immediate' option set to 'true' the watcher is also triggered right after it is created.</p>
  <div>
    <input type="range" min="0" max="10" v-model="value"> Current value: {{ value }}
    <p>Messages from the watcher:</p>
    <ol>
      <li v-for="x in watchMessages">{{ x }}</li>
    </ol>
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: 4,
      watchMessages: []
    };
  },
  mounted() {
    this.$watch('value', (newVal, oldVal) => {
      this.watchMessages.push('Old value: '+oldVal+' New value: '+newVal)
    }, {
      immediate: true
    });
  }
};
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
}

li:first-child {
  background-color: lightgreen;
}</style>
Run Example »

Example 4

Using the stop function returned by the $watch() method to stop the watcher.

<template>
  <h2>Example $watch() Method</h2>
  <p>Drag the slider to see the watcher work, click the stop button, and drag the slider again to confirm that the watcher has now stopped.</p>
  <div>
    <p><input type="range" min="0" max="10" v-model="value"> Current value: {{ value }}</p>
    <button v-on:click="stopFunc">Stop Watcher</button>
    <ol>
      <li v-for="x in results">{{ x }}</li>
    </ol>
  </div>
</template>

<script>
export default {
  data() {
    return {
      value: 4,
      results: [],
      stopFunc: null
    };
  },
  mounted() {
    this.stopFunc = this.$watch('value', function() {
      this.results.push('$watch() method')
    })
  }
};
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
}
</style>
Run Example »

Example 5

Using a dot-delimited path string so that the $watch() method can listen to the 'country' property inside the 'value' object.

<template>
  <h2>Example $watch() Method</h2>
  <p>The watcher is set up to watch 'value.country' and will therefore detect when the country is changed inside the 'value' object.</p>
  <div>
    <p>Register a new country for Stuart to live in:</p>
    <p><input type="text" v-model="inpVal"></p>
    <button v-on:click="regHobby">Register</button>
    <ol>
      <li v-for="x in watchMessages">{{ x }}</li>
    </ol>
  </div>
  <p>Current 'value' object:</p>
  <pre>{{ this.value }}</pre>
</template>

<script>
export default {
  data() {
    return {
      inpVal: null,
      value: {
        owner: 'Stuart',
        address: 'Faraway Lane',
        country: 'Mexico'
      },
      watchMessages: []
    };
  },
  methods: {
    regHobby() {
      this.value.country = this.inpVal;
      this.inpVal = null;
    }
  },
  mounted() {
    this.$watch('value.country', function () {
      this.watchMessages.push('watcher triggered')
    });
  }
};
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
}
</style>
Run Example »

Example 6

Using a function in the $watch() method to listen to changes in more than one value.

<template>
  <h2>Example $watch() Method</h2>
  <p>Using a function as the first argument in the watcher to watch for changes in the sum of value A and value B.</p>
  <div>
    <p>Register a new country for Stuart to live in:</p>
    <p>Value A: <input type="range" min="-10" max="20" v-model="inpValA"> {{ inpValA }}</p>
    <p>Value B: <input type="range" min="-10" max="20" v-model="inpValB"> {{ inpValB }}</p>
    <ol>
      <li v-for="x in watchMessages">{{ x }}</li>
    </ol>
  </div>
</template>

<script>
export default {
  data() {
    return {
      inpValA: 2,
      inpValB: 4,
      watchMessages: []
    };
  },
  mounted() {
    this.$watch( 
      ()=> Number(this.inpValA) + Number(this.inpValB), 
      function (newVal,oldVal) {
        this.watchMessages.push('watcher triggered. A + B = ' + newVal)
      }
    );
  }
};
</script>

<style scoped>
div {
  border: solid black 1px;
  padding: 10px;
}
li {
  background-color: lightgreen;
}
</style>
Run Example »

Related Pages

Vue Tutorial: Vue Watchers

Vue Tutorial: Vue Methods

Vue Tutorial: Vue v-on Directive

Vue Tutorial: Vue Template Refs

Vue Reference: Vue $refs Object

JavaScript Tutorial: JS Arrow Function


Copyright 1999-2023 by Refsnes Data. All Rights Reserved.