[Vuejs]-Vue prop watcher triggered unexpectedly if the prop is assigned to an object directly in template

-1👍

First, the docs: "every time the parent component is updated, all props in the child component will be refreshed with the latest value"

By using v-bind:propA="XX" in the template, you are telling Vue "XX is JavaScript expression and I want to use it as value of propA"
So if you use { value: 'hello' } expression, which is literally "create new object" expression, is it really that surprising new object is created (and in your case watcher executed) every time parent is re-rendered ?

To better understand Vue, it really helps to remember that everything in the template is always compiled into plain JavaScript and use the tool as vue-compiler-online to take a look at the output of Vue compiler.

For example template like this:

<foo :settings="{ value: 'hello' }" />

is compiled into this:

function render() {
    with(this) {
        return _c('foo', {
            attrs: {
                "settings": {
                    value: 'hello'
                }
            }
        })
    }
}

Template like this:

<foo :settings="dataMemberOrComputed" />

is compiled into this:

function render() {
    with(this) {
        return _c('foo', {
            attrs: {
                "settings": dataMemberOrComputed
            }
        })
    }
}

It’s suddenly very clear new object is created every time in the first example, and same reference to an object (same or different …depends on the logic) is used in second example.

I saw some code are assigning object in template directly too, and it feels natural and convenient.

I’m still a Vue newbie but I browse source code of "big" libraries like Vuetify from time to time to learn something new and I don’t think passing "new object" expression into prop is common pattern (how that would be useful?).

What is very common is <foo v-bind="{ propA: propAvalue, propB: propBValue }">Passing the Properties of an Object which is a very different thing…

Leave a comment