admin管理员组

文章数量:1300005

First of all, I am just starting playing with VueJS, so this cannot be a VueJS version thing as suggested here

It might be a duplicate of :

  • How to solve [Vue warn]: Avoid mutating a prop directly since the value will be overwritten on vue.js 2? - the difference is that I am only trying to set the values with v-bind, once.
  • Avoid mutating a prop directly since the value will be overwritten - This also looks somehow similar, but the solution didn't worked for me.
  • What's the correct to modify VUE ponent via javascript? - this solution looks pretty much what I have in my case
  • vuejs update parent data from child ponent

My problem starts with my Html looking like this:

<div id="app">
  <div class="row">
    <div class="form-group col-md-8 col-md-offset-2">
      <birthday-controls
       :birthDay="birthDay"
       :birthMonth="birthMonth"
       :birthYear="birthYear">
      </birthday-controls>
    </div>
  </div>
</div>

and JS:

Vueponent('birthday-controls', {

    template: `<div class="birthday">
    <input type="text" name="year"  placeholder="yyyy" v-model="birthYear" size="4" maxlength="4"/>
    <input type="text" name="month" placeholder="mm" v-show="validYear" v-model="birthMonth" size="3" maxlength="2"/>
    <input type="text" v-show="validYear && validMonth" name="day" placeholder="dd" v-model="birthDay" size="2" maxlength="2"/>
  </div>`,

    props: ['birthDay', 'birthMonth', 'birthYear'],

    puted: {
        validYear: function() {
            return (this.birthYear > new Date().getFullYear()-100 && this.birthYear < new Date().getFullYear()-14)
        },
        validMonth: function() {
            return (this.birthMonth > 0 && this.birthMonth <= 12)
        },
        validDay: function() {
            return (this.birthDay > 0 && this.birthDay <=31) //I have to add more checking here for february, leap years and ....
        }
    }

});

new Vue({
    el: '#app',

    data: function() {
        return {
            birthDay: "",
            birthMonth: "",
            birthYear: ""
        }
    },

});

I have prepared codepen here:

However, the second answer from here: vuejs update parent data from child ponent makes me realise that I'm missing something

In that example it sets an this.$emit('increment') inside one of the methods, and triggers that on specific event.

In this other example: Update a child's data ponent to the father ponent in vue.js using .vue webpack(vue2) , the answer suggest adding a watch to emit the change.

  watch: {
    val() {
      this.$emit('title-updated', this.val);
    }
  }

Now I'm even more confused! What is the right (or best) way to deal with this problem?

Note: If I remove from the initial html :

   :birthDay="birthDay"
   :birthMonth="birthMonth"
   :birthYear="birthYear"

It still works as expected, but I'm still getting that Vue warn, however, if I'm following the method from here: , it stops working, but I'm getting no error.

My Updated code: /

To conclude: I need the functionality from the beginning but without the [Vue warn]

This is what I got in my initial example:

[Vue warn]: 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: "birthYear"

First of all, I am just starting playing with VueJS, so this cannot be a VueJS version thing as suggested here

It might be a duplicate of :

  • How to solve [Vue warn]: Avoid mutating a prop directly since the value will be overwritten on vue.js 2? - the difference is that I am only trying to set the values with v-bind, once.
  • Avoid mutating a prop directly since the value will be overwritten - This also looks somehow similar, but the solution didn't worked for me.
  • What's the correct to modify VUE ponent via javascript? - this solution looks pretty much what I have in my case
  • vuejs update parent data from child ponent

My problem starts with my Html looking like this:

<div id="app">
  <div class="row">
    <div class="form-group col-md-8 col-md-offset-2">
      <birthday-controls
       :birthDay="birthDay"
       :birthMonth="birthMonth"
       :birthYear="birthYear">
      </birthday-controls>
    </div>
  </div>
</div>

and JS:

Vue.ponent('birthday-controls', {

    template: `<div class="birthday">
    <input type="text" name="year"  placeholder="yyyy" v-model="birthYear" size="4" maxlength="4"/>
    <input type="text" name="month" placeholder="mm" v-show="validYear" v-model="birthMonth" size="3" maxlength="2"/>
    <input type="text" v-show="validYear && validMonth" name="day" placeholder="dd" v-model="birthDay" size="2" maxlength="2"/>
  </div>`,

    props: ['birthDay', 'birthMonth', 'birthYear'],

    puted: {
        validYear: function() {
            return (this.birthYear > new Date().getFullYear()-100 && this.birthYear < new Date().getFullYear()-14)
        },
        validMonth: function() {
            return (this.birthMonth > 0 && this.birthMonth <= 12)
        },
        validDay: function() {
            return (this.birthDay > 0 && this.birthDay <=31) //I have to add more checking here for february, leap years and ....
        }
    }

});

new Vue({
    el: '#app',

    data: function() {
        return {
            birthDay: "",
            birthMonth: "",
            birthYear: ""
        }
    },

});

I have prepared codepen here: http://codepen.io/AngelinCalu/pen/OpXBay

However, the second answer from here: vuejs update parent data from child ponent makes me realise that I'm missing something

In that example it sets an this.$emit('increment') inside one of the methods, and triggers that on specific event.

In this other example: Update a child's data ponent to the father ponent in vue.js using .vue webpack(vue2) , the answer suggest adding a watch to emit the change.

  watch: {
    val() {
      this.$emit('title-updated', this.val);
    }
  }

Now I'm even more confused! What is the right (or best) way to deal with this problem?

Note: If I remove from the initial html :

   :birthDay="birthDay"
   :birthMonth="birthMonth"
   :birthYear="birthYear"

It still works as expected, but I'm still getting that Vue warn, however, if I'm following the method from here: https://stackoverflow./a/41901150/2012740, it stops working, but I'm getting no error.

My Updated code: https://jsfiddle/angelin8r/647m7vdf/

To conclude: I need the functionality from the beginning but without the [Vue warn]

This is what I got in my initial example:

[Vue warn]: 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: "birthYear"

Share Improve this question edited May 23, 2017 at 12:25 CommunityBot 11 silver badge asked Mar 5, 2017 at 21:25 Angelin CaluAngelin Calu 1,9158 gold badges24 silver badges48 bronze badges 2
  • Do you need birthYear, birthMonth, or birthDay to be changed outside the ponent? As in, when it changes in the ponent, something outside the ponent knows? – Bert Commented Mar 5, 2017 at 21:41
  • Actually, I only need to change them inside the ponent. Probably I will store them into the DB somehow inside the birthday-controls ponent. – Angelin Calu Commented Mar 5, 2017 at 21:43
Add a ment  | 

1 Answer 1

Reset to default 6

The warning is the result of setting v-model to the value of your properties. The reason is because if you change birthYear, birthMonth, or birthDay outside the ponent, then whatever the value is currently inside the ponent will be immediately overwritten.

Instead, capture a copy.

Vue.ponent('birthday-controls', {

    template: `<div class="birthday">
    <input type="text" name="year"  placeholder="yyyy" v-model="internalBirthYear" size="4" maxlength="4"/>
    <input type="text" name="month" placeholder="mm" v-show="validYear" v-model="internalBirthMonth" size="3" maxlength="2"/>
    <input type="text" v-show="validYear && validMonth" name="day" placeholder="dd" v-model="internalBirthDay" size="2" maxlength="2"/>
  </div>`,

    props: ['birthDay', 'birthMonth', 'birthYear'],

    data(){
      return {
        internalBirthDay: this.birthDay,
        internalBirthMonth: this.birthMonth, 
        internalBirthYear: this.birthYear
      }
    },

    puted: {
        validYear: function() {
            return (this.internalBirthYear > new Date().getFullYear()-100 && this.internalBirthYear < new Date().getFullYear()-14)
        },
        validMonth: function() {
            return (this.internalBirthMonth > 0 && this.internalBirthMonth <= 12)
        },
        validDay: function() {
            return (this.internalBirthDay > 0 && this.internalBirthDay <=31) //I have to add more checking here for february, leap years and ....
        }
    }

});

You did this almost exactly in your fiddle, but you did not correct your puted values.

puted: {
    validYear: function() {
        return (this.birthYear > new Date().getFullYear()-100 && this.birthYear < new Date().getFullYear()-14)
    },
    validMonth: function() {
        return (this.birthMonth > 0 && this.birthMonth <= 12)
    },
    validDay: function() {
        return (this.birthDay > 0 && this.birthDay <=31) //I have to add more checking here for february, leap years and stuff
    }
},

should be

puted: {
    validYear: function() {
        return (this.var_birthYear > new Date().getFullYear()-100 && this.var_birthYear < new Date().getFullYear()-14)
    },
    validMonth: function() {
        return (this.var_birthMonth > 0 && this.var_birthMonth <= 12)
    },
    validDay: function() {
        return (this.var_birthDay > 0 && this.var_birthDay <=31) //I have to add more checking here for february, leap years and stuff
    }
},

本文标签: javascriptAvoid mutating a prop directly in VueJS 2Stack Overflow