Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify props.value from within child component

Tags:

vue.js

vuejs2

I am new to Vue and trying to build a "dropdown" component. I want to use it from a parent component like this:

<my-dropdown v-model="selection"></my-dropdown>

where selection is stored as data on the parent, and should be updated to reflect the user's selection. To do this I believe my dropdown component needs a value prop and it needs to emit input events when the selection changes.

However, I also want to modify the value from within the child itself, because I want to be able to use the dropdown component on its own (I need to modify it because otherwise the UI will not update to reflect the newly selected value if the component is used on its own).

Is there a way I can bind with v-model as above, but also modify the value from within the child (it seems I can't, because value is a prop and the child can't modify its own props).

like image 737
Flash Avatar asked Feb 02 '18 03:02

Flash


People also ask

Can props be modified by child component?

A component cannot update its own props unless they are arrays or objects (having a component update its own props even if possible is an anti-pattern), but can update its state and the props of its children.

Can you modify the values of props?

You can't change the value of props but you still have options to change values that you can use. You have two options: Either you change it from the parent component or you use state instead of props. Where ChildComponent has your code to use this.props.name .

Can we change props in child component in Vuejs?

In addition, every time the parent component is updated, all props in the child component will be refreshed with the latest value. This means you should not attempt to mutate a prop inside a child component. If you do, Vue will warn you in the console.


2 Answers

You need to have a computed property proxy for a local value that handles the input/value values.

props: {
  value: {
    required: true,
  }
},
computed: {
  mySelection: {
    get() {
      return this.value;
    },
    set(v) {
      this.$emit('input', v)
    }
  }
}

Now you can set your template to use the mySelection value for managing your data inside this component and as it changes, the data is emitted correctly and is always in sync with the v-model (selected) when you use it in the parent.

like image 145
Brandon Deo Avatar answered Oct 04 '22 08:10

Brandon Deo


Vue's philosophy is: "props down, events up". It even says this in the documentation: Composing Components.

Components are meant to be used together, most commonly in parent-child relationships: component A may use component B in its own template. They inevitably need to communicate to one another: the parent may need to pass data down to the child, and the child may need to inform the parent of something that happened in the child. However, it is also very important to keep the parent and the child as decoupled as possible via a clearly-defined interface. This ensures each component’s code can be written and reasoned about in relative isolation, thus making them more maintainable and potentially easier to reuse.

In Vue, the parent-child component relationship can be summarized as props down, events up. The parent passes data down to the child via props, and the child sends messages to the parent via events. Let’s see how they work next.

Don't try to modify the value from within the child component. Tell the parent component about something and, if the parent cares, it can do something about it. Having the child component change things gives too much responsibility to the child.

like image 43
zero298 Avatar answered Oct 04 '22 07:10

zero298