Is it possible to change props value from method in Vue component?

66,777

Solution 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.

Solution 2

Another approach is using a computed property for handling props:

{
  template: '#navigation-form',
  props: ['propRoomSelected'],
  data () {
    return {
      roomSelected: this.computedRoomSelected,
      changeableRoomSelected: undefined
    }
  },
  computed: {
    computedRoomSelected () {
      if (this.changeableRoomSelected !== undefined) {
        return this.changeableRoomSelected
      }
      return this.propRoomSelected
    }
  },
  methods: {
    updateCoachStatus (event) {
      this.changeableRoomSelected = 67
    }
  }
}
Share:
66,777

Related videos on Youtube

Rubanraj Ravichandran
Author by

Rubanraj Ravichandran

Updated on July 31, 2022

Comments

  • Rubanraj Ravichandran
    Rubanraj Ravichandran almost 2 years

    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??

    • Dacredible
      Dacredible over 5 years
      is it true that if the data in child component is in an <input> tag, the emit and update can be omitted? I'm asking because I'm copying the props to local and mutate the local by v-model in an <input>, the props got automatically updated.
    • Rubanraj Ravichandran
      Rubanraj Ravichandran over 5 years
      How are you copying the data? Are you doing clone or deepClone, else just assigning the prop value to data in your child component? If you do assign prop value directly to child component data, then the local data still have the reference of parent data. So, technically it will update the prop data too.
  • carmolim
    carmolim over 2 years
    what if I need to update 3 or more properties, I need to create a method for each property and handle each one separately or there's a better approach?