Watchers not triggered on initialization

Hi,

First of all, vue is really great!

I’ve encountered some problems using watchers.

It seems that watchers are not triggered when the vue instance (or component) is being created. Only subsequent changes of the prop trigger the watch function.
To get things working (to avoid missing the initial value of the prop) I have to repeat the watch function in the mounted hook:

module.exports = {
    props: ["test"],
    watch: {
        test: function(value) {
            if (value) {
                //Do some stuff
                this.initSomething();
            }
        }
    },
    methods: {
        initSomething: function() {
        }
    },
    mounted: function() {
        if (this.test) {
            //Do the same stuff as above
            this.initSomething();
        }
    }
};

Is this behaviour intended? And if so, why? Shouldn’t initializing the prop be regarded as a change of the prop (prop changes its value from undefined to something else)?

Are you aware of any other (more elegant) ways to accomplish the above?

Thank you.

3 Likes
watch: {
  test: {
    immediate: true,
    handler(newVal, oldVal) {
      console.log(newVal, oldVal)
    },
  },
},
10 Likes

Thank you! I didn’t realize that the immediate option was exactly what i was looking for. (Thought this had to do with sync/async stuff.)

Is there any documentation on using watcher options in the watch object directly (without using the $watch function)?

It’s not really in the docs directly. You kind of have to look at 2 different places to realize you can do it:

https://vuejs.org/v2/api/#watch and https://vuejs.org/v2/api/#vm-watch

as well as in the source

2 Likes

If you don’t define a prop default it will be undefined.

And, no, the watch handler will not trigger immediately unless you use immediate: true.

That is exactly what happens.

in your example the prop is always defined so the default value never gets used.

I’m not really sure what you are asking.

A watch handler executes every time the value it is watching changes.
If you use immediate: true then the watch handler also execute once with the initial value.

Thats all there is to it.

It isn’t possible to do this. The handler will execute for every change.

In your example you have named the values incorrectly. The default value is defined as “initial value”, the initial value is defined as “1st change”, and the first change is defined as “2nd change”. Passing a prop to a component is not a “change” - the watch handler doesn’t execute. If you want the handler to execute immediately, you use immediate: true so that it does.

1 Like

Then you aren’t actally understanding how it works.

There are any number of situations where you would want this. The example in the docs is one of them https://vuejs.org/v2/guide/computed.html#Watchers.

The example in the docs is just that.