Is it possible to change props value from method i

2019-06-19 22:59发布

问题:

I have a component and i am passing value 543 to props :prop-room-selected,

<navigation-form :prop-room-selected='543'>
</navigation-form>

Now, From a button click, i am calling the function updateCoachStatus to change the value of propRoomSelected, but the props value is not updating.

{
    template: '#navigation-form',
    props: ['propRoomSelected'],
    data: function () {
      return {
        roomSelected: this.propRoomSelected,
      }
  },
  methods:{
      updateCoachStatus: function(event){
         this.propRoomSelected = 67;
      }
  }
}

I dont know how to change the value of props from function. Is it possible in Vue to update the value of props??

回答1:

What you are doing will throw a warning in Vue (in the console).

[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: "propRoomSelected"

The value will actually change inside the component, but not outside the component. The value of a parent property cannot be changed inside a component, and, in fact, the updated value will be lost if the parent re-renders for any reason.

To update the parent property, what you should do is $emit the updated value and listen for the change in the parent.

Vue.component("navigation-form",{
    template: '#navigation-form',
    props: ['propRoomSelected'],
    data: function () {
      return {
        roomSelected: this.propRoomSelected,
      }
  },
  methods:{
      updateCoachStatus: function(event){
         this.$emit("update-room-selected", 67) ;
      }
  }
})

And in your parent template listen for the event

<navigation-form :prop-room-selected='propRoomSelected'
                 @update-room-selected="onUpdatePropRoomSelected">
</navigation-form>

Here is an example.

This is a common pattern and Vue implemented a directive to make it slightly easier called v-model. Here is a component that supports v-model that will do the same thing.

Vue.component("navigation-form-two",{
    template: '#navigation-form-two',
    props: ['value'],
    data: function () {
      return {
        roomSelected: this.value,
      }
  },
  methods:{
      updateCoachStatus: function(event){
         this.$emit("input", 67) ;
      }
  }
})

And in the parent template

<navigation-form-two v-model="secondRoomSelected">

Essentially, for your component to support v-model you should accept a value property and $emit the input event. The example linked above also shows that working.