Questions regarding handling immutable props and mutable (data) props

I have two (:yum:) questions (I am using vue 2.0.1)

QUESTION 1

The official guide says

Mutating a prop locally is now considered an anti-pattern
Most use cases of mutating a prop can be replaced by one of these options:

  • a data property, with the prop used to set its default value
  • a computed property

I did the first

In the html file

<alert-box :type="'success'">

in the js file

var myComp = Vue.component('alert-box', {
    template: '#',
    props: ['type'], //Immutable, to mutate locally must declare a local copy in data object
    data: function () {
        return {
            type: this.type // Local mutable prop
        };
    },
    created() {
    this.type = "updated type"
        console.log(this.type);
    }
});

Now raises the following warnings:

vue.js:2574 [Vue warn]: The data property "type" is already declared as a prop. Use prop default value instead. (found in component <alert-box>)

vue.js:2574 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "type" (found in component <alert-box>)

If I use a different name for the immutable prop (lets say “type1”) the warnings disappear

/* ... */
props: ['type1'],
data: function () {
    return {
        
        type: this.type1
    };
},
/* ... */

So is it considered bad practice to mutate a prop by declaring a field in the data with the same name as the immutable prop ? Are those warnings reasonable?

QUESTION 2

did another example

var myComp = Vue.component('alert-box', {
    template: '#alert-box-template',
    props: ['foo'],
    data: function () {
        return {
            foo: "baz"
        };
    },
    computed: {},
    created() {
    console.log(foo);
    }
});

It outputs “bar” and not “baz”. I m just wondering why is that happening ?:confused:

Props, data properties, methods, computed properties all share the same "namespace as they are all mapped to properties in the component instance.

So yes, you should never use a name twice, and. Is does not only apply to props and data.

2 Likes

Thank you for your answer! However i think I am still a little bit confused regarding my 2nd question, so, could you please also explain why console.log(foo) outputs the value of the immutable prop and not the value of the mutable data property ?

Because props are mapped to the component instance first. When Vue then tries to map the data properties in the component instance, the foo prop is already taken.

I think I’m development mode you should see a warning in the console about duplicate names?

1 Like

Thank you @LinusBorg , your answer made the things clear for me

I actually I get the following warning:
[Vue warn]: The data property "foo" is already declared as a prop. Use prop default value instead. (found in component <alert-box>)

IMHO in these scenarios , a warning message that actually says about “duplicate names” would be more clear and helpful.