避免直接在VueJS 2中改变道具 [英] Avoid mutating a prop directly in VueJS 2

查看:84
本文介绍了避免直接在VueJS 2中改变道具的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我刚刚开始玩VueJS,所以这不是VueJS版本的东西

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

它可能是重复的:

  • 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 component via javascript? - this solution looks pretty much what I have in my case
  • vuejs update parent data from child component

我的问题始于我的Html,如下所示:

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>

和JS:

Vue.component('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'],

    computed: {
        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: ""
        }
    },

});

我在这里编写了代码: http://codepen.io/AngelinCalu/pen/OpXBay

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

然而,第二个答案来自这里: vuejs更新来自子组件的父数据让我意识到我'我错过了什么

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

在这个例子中它设置了一个这个。$ emit('increment')里面的一个方法,并触发特定事件。

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

在另一个例子中:使用.vue webpack(vue2)将子数据组件更新到vue.js中的父组件,答案建议添加监视以发出更改。

In this other example: Update a child's data component to the father component 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?

注意:
如果我从最初的 html中删除

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

它仍然按预期工作,但我仍然得到那个Vue但是,如果我从这里开始遵循这个方法,请发出警告: https://stackoverflow.com/a/41901150/2012740,它停止工作,但我没有收到任何错误。

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

我的更新代码: https://jsfiddle.net/angelin8r/647m7vdf/

总结:我从一开始就需要功能但是没有 [Vue警告]

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

这是我在初始示例中得到的结果:

This is what I got in my initial example:


[Vue警告]:避免直接改变道具,因为该值将被覆盖每当父组件重新渲染时。而是根据prop的值使用数据或计算属性。支持变异:birthYear

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


推荐答案

警告是设置<$ c的结果$ c> v-model 到您的属性的值。原因是因为如果你改变了birthYear,birthMonth或birthDay outside 这个组件,那么当前里面的任何值都将被立即覆盖。

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 component, then whatever the value is currently inside the component will be immediately overwritten.

取而代之的是获取副本。

Instead, capture a copy.

Vue.component('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
      }
    },

    computed: {
        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 computed values.

computed: {
    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
    }
},

computed: {
    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
    }
},

这篇关于避免直接在VueJS 2中改变道具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆