最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vue2: warning: Avoid mutating a prop directly - Stack Overflow

programmeradmin6浏览0评论

I'm stuck in the situation where my child ponent (autoplete) needs to update a value of its parent (Curve), And the parent needs to update the one of the child (or to pletely re-render when a new Curve ponent is used)

In my app the user can select a Curve in a list of Curve ponents. My previous code worked correctly except the ponent autoplete was not updated when the user selected another Curve in the list (the ponent didn't update its values with the value of the parent).

This problem is fixed now but I get this warning:

Avoid mutating a prop directly since the value will be overwritten whenever the parent ponent re-renders. Instead, use a data or puted property based on the prop's value. Prop being mutated: "value"

The description of this warning explain exactly what behavior I expect from my ponents. Despite this warning, this code works perfectly fine !

Here is the code (parts of it have been removed to simplify)

// curve.vue
<template>
  <autoplete v-model="curve.y"></autoplete>
</template>


<script>
  import Autoplete from './autoplete'

  export default {
    name: 'Curve',
    props: {
      value: Object
    },
    puted: {
      curve() { return this.value }
    },
    ponents: { Autoplete }
  }
</script>


// autoplete.vue
<template>
    <input type="text" v-model="content"/>
</template>

<script>
  export default {
    name: 'Autoplete',
    props: {
      value: {
        type: String,
        required: true
      }
    },
    puted: {
      content: {
        get() { return this.value },
        set(newValue) { this.value = newValue }
      }
    }
  }
</script>

A lot of people are getting the same warning, I tried some solutions I found but I was not able to make them work in my situation (Using events, changing the type of the props of Autoplete to be an Object, using an other puted value, ...)

Is there a simple solution to solve this problem ? Should I simply ignore this warning ?

I'm stuck in the situation where my child ponent (autoplete) needs to update a value of its parent (Curve), And the parent needs to update the one of the child (or to pletely re-render when a new Curve ponent is used)

In my app the user can select a Curve in a list of Curve ponents. My previous code worked correctly except the ponent autoplete was not updated when the user selected another Curve in the list (the ponent didn't update its values with the value of the parent).

This problem is fixed now but I get this warning:

Avoid mutating a prop directly since the value will be overwritten whenever the parent ponent re-renders. Instead, use a data or puted property based on the prop's value. Prop being mutated: "value"

The description of this warning explain exactly what behavior I expect from my ponents. Despite this warning, this code works perfectly fine !

Here is the code (parts of it have been removed to simplify)

// curve.vue
<template>
  <autoplete v-model="curve.y"></autoplete>
</template>


<script>
  import Autoplete from './autoplete'

  export default {
    name: 'Curve',
    props: {
      value: Object
    },
    puted: {
      curve() { return this.value }
    },
    ponents: { Autoplete }
  }
</script>


// autoplete.vue
<template>
    <input type="text" v-model="content"/>
</template>

<script>
  export default {
    name: 'Autoplete',
    props: {
      value: {
        type: String,
        required: true
      }
    },
    puted: {
      content: {
        get() { return this.value },
        set(newValue) { this.value = newValue }
      }
    }
  }
</script>

A lot of people are getting the same warning, I tried some solutions I found but I was not able to make them work in my situation (Using events, changing the type of the props of Autoplete to be an Object, using an other puted value, ...)

Is there a simple solution to solve this problem ? Should I simply ignore this warning ?

Share Improve this question asked Sep 23, 2017 at 19:48 MichaelMichael 5396 silver badges12 bronze badges 1
  • 1 in the doc: for a ponent to work with v-model you need to accept a value prop and emit an input event !! – hannes neukermans Commented Sep 23, 2017 at 21:29
Add a ment  | 

2 Answers 2

Reset to default 4

you can try is code, follow the prop -> local data -> $emit local data to prop flow in every ponent and ponent wrapper.

ps: $emit('input', ...) is update for the value(in props) bind by v-model

// curve.vue
<template>
  <autoplete v-model="curve.y"></autoplete>
</template>


<script>
  import Autoplete from './autoplete'

  export default {
    name: 'Curve',
    props: {
      value: Object
    },
    data() {
      return { currentValue: this.value }
    }
    puted: {
      curve() { return this.currentValue }
    },
    watch: {
      'curve.y'(val) {
        this.$emit('input', this.currentValue);
      }
    },
    ponents: { Autoplete }
  }
</script>


// autoplete.vue
<template>
  <input type="text" v-model="content"/>
</template>

<script>
  export default {
    name: 'Autoplete',
    props: {
      value: {
        type: String,
        required: true
      }
    },
    data() {
      return { currentValue: this.value };
    },
    puted: {
      content: {
        get() { return this.value },
        set(newValue) {
          this.currentValue = newValue; 
          this.$emit('input', this.currentValue);
        }
      }
    }
  }
</script>

You can ignore it and everything will work just fine, but it's a bad practice, that's what vue is telling you. It'll be much harder to debug code, when you're not following the single responsibility principle.

Vue suggests you, that only the ponent who owns the data should be able to modify it.

Not sure why events solution ($emit) does not work in your situation, it throws errors or what?

To get rid of this warning you also can use .sync modifier: https://v2.vuejs/v2/guide/ponents.html#sync-Modifier

发布评论

评论列表(0)

  1. 暂无评论