[solve] Open/close children's dialog from parent => Avoid mutating a prop directly since the value will be...



  • Hi all,

    I have a menu in a parent.
    When I click on the menu button, I want to trigger a dialog in a child.

    This works well, except when the user clicks on the dialog overlay to close it.

    How to spend a $ emit on click on the overlay?
    Actually, if an user clic on overlay i have this error:

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

    The parent’s watered-down code:

    <template>
    <component :options="this.options" :is="componentName" @update-options="optionsProps"></component>
    <q-btn
            fab
            color="positive"
            icon="fas fa-cog"
            class="absolute-center no-shadow"
            @click="optionsProps"
            style="border: 4px solid white; top: 0; right: 0; transform: translateX(-50%), translateY(-30%);"
          />
    </template>
    <script>
    export default {
        data () {
            return {
              options: true
           }
        },
        methods: {
            optionsProps () {
                this.options === true ? this.options = false : this.options = true
                return this.options
            }
        }
    ...
    
    

    The child’s watered-down code

    <template>
        <q-card>
            <q-dialog square full-width v-model="options" position="bottom" class="">
                <q-card-section class="row items-center">
                    <div class="text-h6">{{ title }}</div>
                    <q-space />
                    <q-btn icon="close" flat round dense @click="close" />
                </q-card-section>
            <q-card-section class="items-center no-wrap">....</q-card-section>
        </q-card>
    </template>
    <script>
    export default {
        props: {
            options: { type: Boolean, default: false }
        },
        methods: {
           activate: function (el) {
                this.$emit('update-options', false)
                this.filter = el
            },
            close () {
                this.$emit('update-options', false)
            }
        }
    }...
    

    Thanks for your help,



  • On your child qdialog, you are using props options as v-model, which v-model is mutating it. Use a local data in your child component instead.



  • Thank you for your answer, however, I do not understand what you want me to do.

    You propose that I create a new data replacing “options” in the v-model? and I suppose I have to create a watcher to follow and modify this new data according to the evolution of options?



  • @Shoooryuken
    This is a common Vue error. You should never modify the props.
    Instead create a computed property which returns options and on update emit an event to parent.

    Something on the line of this:

    <template>
        <q-card>
            <q-dialog square full-width v-model="$_options" position="bottom" class="">
                <q-card-section class="row items-center">
                    <div class="text-h6">{{ title }}</div>
                    <q-space />
                    <q-btn icon="close" flat round dense @click="close" />
                </q-card-section>
            <q-card-section class="items-center no-wrap">....</q-card-section>
        </q-card>
    </template>
    <script>
    export default {
        props: {
            options: { type: Boolean, default: false }
        },
        computed: {
            $_options: {
                get: function () {
                    return this.options;
                },
                set: function (val) {
                    this.$emit('update-options', val);
                }
            }
        },
        methods: {
           activate: function (el) {
                this.$emit('update-options', false)
                this.filter = el
            },
            close () {
                this.$emit('update-options', false)
            }
        }
    }...
    

    https://forum.vuejs.org/t/vue-warn-avoid-mutating-a-prop-directly-since-the-value-will-be-overwritten-whenever-the-parent-component-re-renders/21757



  • Now that I see the solution, I understand.
    thank you so much


Log in to reply