1

I use Quasar framework in Version 1.6.2. and want to use a component (Drawer.vue) for my drawer. The component is used in my layout file (MainLayout.vue).

I get the following error message in my console:

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

The drawer works, but not on the first click – only on subsequent clicks.

What is the correct way to pass the parents model to my drawer?

Component: Drawer.vue

<template>
    <q-drawer show-if-above v-model="rightDrawerOpen" side="right" bordered>
        <q-list>
            <q-item-label header>Menü</q-item-label>
        </q-list>
    </q-drawer>
</template>

<script>
export default {
    name: "Drawer",
    props: {
        rightDrawerOpen: Boolean
    }
};
</script>

Parent: MainLayout.vue

<Drawer :right-drawer-open="rightDrawerOpen" />
Daniel Sixl
  • 2,488
  • 2
  • 16
  • 29

1 Answers1

1

I would move the q-drawer component back into the MainLayout.vue component, then put the q-list into the child component. Then toggling "rightDrawerOpen" will occur in the "data" of MainLayout.vue instead of on the props of the child component which is where the error is coming from. Example:

MainLayout.vue:

<template>
    <q-layout>

        <q-drawer show-if-above v-model="rightDrawerOpen" side="right" bordered>
            <DrawerContents />
        </q-drawer>

        <q-page-container>
            <router-view />
        </q-page-container>

    </q-layout>
</template>

<script>
import DrawerContents from './DrawerContents.vue';

export default {
    components: {
        DrawerContents,
    },
    data() {
        return {
            rightDrawerOpen: true,
        };
    },
};
</script>

DrawerContents.vue:

<template>
    <q-list>
        <q-item-label header>Menü</q-item-label>
    </q-list>
</template>
brandondavid
  • 201
  • 1
  • 8
  • Thank you for your answer David! This actually was my first solution. I ran into problems having another wrapper element then. Unfortunately Vue does not support fragments yet, it allows only one root node. I need a `` as a direct descendant, it stops working otherwise. I was thinking about using a plugin first, but didn't like the idea of an additional package (https://www.npmjs.com/package/vue-fragment). – Daniel Sixl Apr 29 '20 at 09:30
  • My structure is like this: ``. By moving this into a sub-component, the scroll-area stopped working due to the additional wrapper-element in between. – Daniel Sixl Apr 29 '20 at 09:43
  • Are you referring to the error you'd get if you put multiple elements in the child component? If so you can wrap the entire child element template in a div like this: – brandondavid Apr 29 '20 at 13:12
  • I should point out that what I posted above isn't the only solution, I assumed it was the best for your situation because (I have a project with the exact same layout).. if you must make the "mutation" happen in the child component there are a couple ways to achieve it using either watchers or computed properties. Here is a nice solution using computed property with explicit setters and getters: https://stackoverflow.com/a/51722100/7412551 – brandondavid Apr 29 '20 at 13:24
  • Thank you very much David! The link you posted was very helpful. It's working now. I added a model property (https://vuejs.org/v2/api/#model) to to define which prop is associated: https://github.com/Sixl-Daniel/sixl.org-SPA-2020/blob/dev/src/components/Drawer.vue – Daniel Sixl Apr 29 '20 at 15:00