0
votes

So I have the following piss of code in my child component

   props: {
        prop_accounts: Array,
        prop_pushing_destination: String,
        prop_selected_account: String,
        prop_selected: Boolean,
        shop_settings: Object,
        name_of_selected_account_field: String
    },

    data() {
        return {
            accounts: this._.cloneDeep(this.prop_accounts),
            pushing_destination: this._.cloneDeep(this.prop_pushing_destination),
            selected_account: this._.cloneDeep(this.prop_selected_account),
            selected: this._.cloneDeep(this.prop_selected)
        }
    },

The parent props pass all the props and all seams to work well but the parent is constantly sampling the backend for changes and if they acquire it updates the props of child and although I can see that props are changed the data stays the same now if I throw the data and use props directly all works well but I get the following warning

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: "selected_account"

1
What are you actually trying to do here? How are these values used? I can't think of any good reason you would need to deep clone props.James Coyle
The props are initial data for the component this data can be changed for example selected account can be changed. And since changing, a prop is an anty pattern I am cloning themurag

1 Answers

0
votes

There are two ways you could handle this: use the props directly and emit changes to the parent; or use computed properties to compute the value based on the data and props.

Emitting changes is probably what you want to do 99% of the time as any changes to the props either internal or external will change what your component is doing. Using computed props allows for changes to the props to be used only if the data hasn't been modified internally.

Computed props

props: {
    defaultAccounts: Array,
    defaultSelected: Boolean,
    ...
}

data: () => ({
    customAccounts: null,
    customSelected: null,
})

computed: {
    accounts() {
        return (this.customAccounts == null) ? this.defaultAccounts : this.customAccounts
    },

    selected() {
        return (this.customSelected == null) ? this.defaultSelected : this.customSelected
    }
}

You could even define setters on the computed props to set the value of the data properties.

Emit changes

Component:

props: {
    accounts: Array,
    selected: Boolean,
    ...
}

methods: {
    accountsChanged(value) {
        this.$emit('update:accounts', value)
    },
    selectedChanged(value) {
        this.$emit('update:selected', value)
    }
}

Where you use component:

<my-component :accounts.sync="accounts" :selected.sync="false"></my-component>

See Sync Modifier Documentation for more info.

I haven't tested this code so it may need tweaking to get it working correctly.