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

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

问题描述

首先,我刚刚开始使用 VueJS,所以这不可能是 VueJS 版本的建议 这里

它可能与以下内容重复:

我的问题始于我的 Html 看起来像这样:

<div class="row"><div class="form-group col-md-8 col-md-offset-2"><生日控制:birthDay="生日":birthMonth="出生月":birthYear="birthYear"></生日控制>

和JS:

Vue.component('生日控件', {模板:`<div class="生日"><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>`,道具:['birthDay','birthMonth','birthYear'],计算:{有效年份:函数(){return (this.birthYear > new Date().getFullYear()-100 && this.birthYear < new Date().getFullYear()-14)},有效月份:函数(){返回(this.birthMonth > 0 && this.birthMonth <= 12)},有效日:函数(){return (this.birthDay > 0 && this.birthDay <=31)//我必须在这里为二月、闰年和...添加更多检查.}}});新的 Vue({el: '#app',数据:函数(){返回 {生日: "",出生月: "",出生年: ""}},});

我在这里准备了 codepen:http://codepen.io/AngelinCalu/pen/OpXBay

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

在该示例中,它在其中一个方法中设置了一个 this.$emit('increment'),并在特定事件上触发.

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

 观看:{瓦尔(){this.$emit('title-updated', this.val);}}

现在我更糊涂了!处理此问题的正确(或最佳)方法是什么?

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

 :birthDay="birthDay":birthMonth="出生月":birthYear="出生年"

它仍然按预期工作,但我仍然收到 Vue 警告,但是,如果我遵循这里的方法:https://stackoverflow.com/a/41901150/2012740,它停止工作,但我没有收到任何错误.

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

总结:我从一开始就需要功能,但没有[Vue warn]

这是我在最初的例子中得到的:

<块引用>

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

解决方案

警告是将 v-model 设置为属性值的结果.原因是因为如果您在组件之外更改birthYear、birthMonth 或birthDay ,那么无论当前内部 的值是什么,该组件都将立即被覆盖.

相反,捕获一个副本.

Vue.component('生日控件', {模板:`<div class="生日"><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>`,道具:['birthDay','birthMonth','birthYear'],数据(){返回 {internalBirthDay: this.birthDay,internalBirthMonth: this.birthMonth,internalBirthYear: this.birthYear}},计算:{有效年份:函数(){return (this.internalBirthYear > new Date().getFullYear()-100 && this.internalBirthYear < new Date().getFullYear()-14)},有效月份:函数(){返回(this.internalBirthMonth > 0 && this.internalBirthMonth <= 12)},有效日:函数(){return (this.internalBirthDay > 0 && this.internalBirthDay <=31)//我必须在这里添加更多关于二月、闰年和...的检查.}}});

你几乎完全按照你的小提琴做了这件事,但你没有更正你的计算值.

计算:{有效年份:函数(){return (this.birthYear > new Date().getFullYear()-100 && this.birthYear < new Date().getFullYear()-14)},有效月份:函数(){返回(this.birthMonth > 0 && this.birthMonth <= 12)},有效日:函数(){return (this.birthDay > 0 && this.birthDay <=31)//我必须在这里添加更多关于二月、闰年和其他东西的检查}},

应该是

计算:{有效年份:函数(){return (this.var_birthYear > new Date().getFullYear()-100 && this.var_birthYear < new Date().getFullYear()-14)},有效月份:函数(){返回(this.var_birthMonth > 0 && this.var_birthMonth <= 12)},有效日:函数(){return (this.var_birthDay > 0 && this.var_birthDay <=31)//我必须在这里添加更多关于二月、闰年和其他东西的检查}},

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 :

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

});

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

However, the second answer from here: vuejs update parent data from child component 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 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?

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.com/a/41901150/2012740, it stops working, but I'm getting no error.

My Updated code: https://jsfiddle.net/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 component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "birthYear"

解决方案

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
    }
},

should be

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 中直接改变 prop的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆