Avoid mutating a prop directly since the value will be overwritten

前端 未结 11 886
被撕碎了的回忆
被撕碎了的回忆 2020-12-10 01:07

I have very common problem with upgrading to Vue 2.0

I am getting warning:

Avoid mutating a prop directly since the value will be overwritte

相关标签:
11条回答
  • 2020-12-10 01:39

    You should make a computed property with a getter and setter and then use $emit to update the property, e.g:

    var GuestMenu = Vue.extend({
        props: ['username', 'password'],
        template: `
        <div id="auth">
            <form class="form-inline pull-right">
                <div class="form-group">
                    <label class="sr-only" for="UserName">User name</label>
                  <input type="username" v-model="usernameInput" class="form-control" id="UserName" placeholder="username">
                </div>
                <div class="form-group">
                  <label class="sr-only" for="Password">Password</label>
                  <input type="password" v-model="passwordInput" class="form-control" id="Password" placeholder="Password">
                </div>
            </form>
        </div>`,
        computed: {
            usernameInput: {
                get: function(){
                    return this.username;
                },
                set: function(newValue){
                    this.$emit('update:username', newValue)
                }   
            },
            passwordInput: {
                get: function(){
                    return this.password;
                },
                set: function(newValue){
                    this.$emit('update:password', newValue)
                }   
            },
        }
    });
    
    0 讨论(0)
  • 2020-12-10 01:43

    Vue.js consider this as anti-pattern. For example, declaring and setting some props like

    this.propsVal = 'new Props Value'
    

    So to solve this issue you have to take in value from the props to data or computed property of Vue instance. like...

    props: ['propsVal'],
    data: function() {
       return {
           propVal: this.propsVal
       };
    },
    methods: {
    ...
    }
    

    and you can use your props value like normally.

    0 讨论(0)
  • 2020-12-10 01:44

    if you want to mutate props - use object.

    <component :user="global.user"></component>
    

    component:

        props: ['user'],
        methods: {
          setUser: function() {
            this.user.username= "User";
            this.user.password= "myPass123";
          }
        }
    
    0 讨论(0)
  • 2020-12-10 01:45

    When you use v-bind the property is bind using two directions, that is why you get the warning.

    If you need to pass the initial username from the parent Vue component, you can use v-bind with another data property such as _username and copy the initial value from the property to the internal data when the component is created:

    props : ['username', 'password'],
    data () {
      return {
        _username: this.username,
        _password: this.password
      }
    }
    

    Edit: you can also use a $watch to update the _username / _password component data when the properties change.

    0 讨论(0)
  • 2020-12-10 01:49

    you can use the emit, then:

    <text-document :title.sync="title"></text-document>
    

    to change the value is:

    this.$emit('update:title', newTitle)
    

    or another way:

    this.$emit('update')
    

    and you can get on the template:

    <text-document :update="oneFunctionInMethods()"></text-document>
    
    0 讨论(0)
  • 2020-12-10 01:56

    I'm not sure what exactly you want to achieve but I'll take two options out of it.

    First one: It's all about getting rid of this warning.

    data () {
      return {
        childVal: this.parentVal
      }
    }
    

    Second one: You want to communicate between parent and child.

    If I got it right, this is a basic example of an <input> in a child component communicating with its parent.

    Parent HTML:

    <p>{{ user }}</p>
    <child-component v-model="user">
    

    Parent JS:

    data () {
      return {
        user: 'John'
      }
    }
    

    Child HTML:

    <input v-bind:value="value" @input="$emit('input', $event.target.value)">
    

    Child JS:

    props: ['value']
    

    Working example: http://jsfiddle.net/kf3aLr1u/

    You can also read more about it in the docs https://vuejs.org/v2/guide/components.html.

    0 讨论(0)
提交回复
热议问题