stkhr
stkhr

Reputation: 81

Please tell me how to eliminate errors that are overwritten each time the prop is changed

Even if you look at the error, you don't know what is causing it.
Occurs when changing the size of the screen or clicking.
It says that the variable has been rewritten, but I don't know what to do.
I couldn't find any cause or solution on examination.
How can it be solved?

Error message:

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

main.vue:

<template>
  <v-app>
    <!-- ヘッダー -->
    <Header
      v-bind:leftDrawer="leftDrawer"
      v-on:leftChange="leftChange"
    ></Header>

    <LeftSidebar
      v-bind:leftDrawer="leftDrawer"
      v-on:leftChange="leftChange"
    ></LeftSidebar>

  </v-app>
</template>

<script>
  import Header from "./Header.vue";
  import LeftSidebar from "./LeftSidebar.vue";


  export default {
    data() {
      return {
        leftDrawer: false,
      }
    },
    components:{
        'Header' : Header,
        'LeftSidebar' : LeftSidebar,
    },
    methods: {
      leftChange() {
          this.leftDrawer = !this.leftDrawer;
      },
    }
  }
</script>

=======
Header.vue:

<template>
  <v-app-bar color="primary" dark app clipped-left clipped-right>
    <v-app-bar-nav-icon @click.stop="leftChange"></v-app-bar-nav-icon>
  </v-app-bar>
</template>

<script>
  export default {
    methods: {
      leftChange: function(){
        this.$emit('leftChange');
      },
    }
  }
</script>

=========== LeftSidebar.vue:

<template>
  <v-navigation-drawer app v-model="leftDrawer" clipped class="yellow">
  </v-navigation-drawer>
</template>

<script>
  export default {
    props: {
      leftDrawer: Boolean
    }
  }
</script>

Upvotes: 0

Views: 52

Answers (3)

Eric Guan
Eric Guan

Reputation: 15982

(I removed all props/attributes unrelated to the question)

<v-navigation-drawer v-model="leftDrawer">

This is mutating the leftDrawer prop. Read the docs to learn what v-model actually does.

Try this, but I doubt it'll work. It depends on how v-navigation-drawer implements v-model. Again, this is in the docs "v-model on custom components."

<v-navigation-drawer :value="leftDrawer" @input="$emit('leftChange')">

Even if you look at the error, you don't know what is causing it.

Depends on your vue experience.

EDIT: Mistake in my answer.

@input="$emit('input', $event)" should be @input="$emit('leftChange')".

Because the parent component main.vue is listening for v-on:leftChange="leftChange" on the LeftSidebar.

Upvotes: 1

stilec
stilec

Reputation: 81

I do think it is because of your v-model="leftDrawer" in LeftSidebar.vue. v-model will update the value of the specified variable when it has been internally mutated in the v-navigation-drawer. In your situation, it will try to mutate the value of the passed leftDrawer prop. Hence, the error message.

The solution would be to assign (in LeftSidebar.vue) your leftDrawer prop in a data attribute and use this attribute with v-bind. If you need to communicate this change to your main.vue component, emit the event as you did in Header.

Personal opinion after some projects with this scenario, I find it easier to manage by saving these states in an app or ui vuex store.

Hope this will help

[EDITED]

If the implementation of v-navigation-drawer allows it, the solution presented by @Eric Guan is the way to go

Upvotes: 0

Abhishek Kulkarni
Abhishek Kulkarni

Reputation: 1767

Try this below :

<template>
  <v-navigation-drawer app v-model="left_drawer" clipped class="yellow">
  </v-navigation-drawer>
</template>

<script>
  export default {
    props: {
      leftDrawer: Boolean
    },
    data(){
        return {
              left_drawer : this.defaultSelected()
        }
    },
    methods:{
        defaultSelected(){
              return this.leftDrawer;
        }
     }
</script>

This is because you are mutating a prop directly, so in your child component, first define a variable for your prop and then assign a value to it using a method or a computed property.

Upvotes: 0

Related Questions