Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 809
Rubanraj Ravichandran Avatar asked Apr 29 '17 22:04

Rubanraj Ravichandran


People also ask

Can you modify a prop Vue?

Two main characteristics of Vue props There are two specific things to keep in mind when dealing with props: Props are passed down the component tree to descendents (not up) Props are read-only and cannot be modified (as you may have discovered)

How do you assign a value to a prop in Vue?

To specify the type of prop you want to use in Vue, you will use an object instead of an array. You'll use the name of the property as the key of each property, and the type as the value. If the type of the data passed does not match the prop type, Vue sends an alert (in development mode) in the console with a warning.

How do you mutate Props in Vue?

Vue. js props are not to be mutated as this is considered an Anti-Pattern in Vue. Now your list structure that is passed to the component is referenced and mutated via the data property of your component :-) If you wish to do more than just parse your list property then make use of the Vue component' computed property.

Can you pass a function as a prop Vue?

You can pass strings, arrays, numbers, and objects as props. But can you pass a function as a prop? While you can pass a function as a prop, this is almost always a bad idea. Instead, there is probably a feature of Vue that is designed exactly to solve your problem.


2 Answers

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.

like image 88
Bert Avatar answered Oct 18 '22 07:10

Bert


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
    }
  }
}
like image 23
Ilyich Avatar answered Oct 18 '22 06:10

Ilyich