1

I've been reading posts about v-model but so far the tutorials have been confusing and doesn't really answer my question: How do you achieve two-way data bindings with v-model?

I need to bind a data variable to a child component, and be able to change the variable's value from both the parent side and the child side. What code do I need to put in the child component so when I do <Component v-model="var">, I can update var from both sides?

For this purpose, I would prefer to avoid the store pattern as it is just two components that need to share the data.

3 Answers 3

2

v-model is just an abstraction on top of unidirectional data flow. Essentially, your custom child component needs to do two things:

  • Accept a prop named value.
  • Emit an event named input with new data.

So your child component would be used like this:

<child-component :value="myVal" @input="myVal = $event"></child-component>

In the above code, $event is a special template construct that holds the data which child component has emitted as part of the event payload. The @input event is simply updating myVal value which will again be passed to a child component via :value binding and thus one-way data flow.

Now, this pattern is repeated so many times that Vue.js has provided a simple v-model syntax-sugar which can be used instead of the above code.

<child-component v-model="myVal"></child-component>

Also, if for some reason, you don't want to use value or input as your prop and event, then you can change them using model attribute. Here is the additional documentation for this.

Note that, if you are using Redux/Vuex, then avoid using v-model. For nested data, there is a good chance that you will land up in edge-case scenarios.

Sign up to request clarification or add additional context in comments.

3 Comments

Do you have an example? The explanation above gets mentioned so may times but I have yet to see an example that puts the above concept into action (e.g. modifying the same array in parent and in child)
I think this codepen should help: codepen.io/fuxy22/pen/OWKdzY
@tyteen4a03, For array, make sure to not use mutable methods like push/splice/shift, etc. Use immutable methods like concat, slice and always emit new array from child component.
2

It's not possible to use v-model for two-way data binding as you want to modify the default behavior when you change the input in the child component.

You want to use v-bind to display the value and v-on:input to pass the data back to parent component.

See https://codesandbox.io/s/rj76y5w02o for example.

The first line is just a read-only text. Select dropdown is parent side data mutator and the text box is from the child component.

Basically, you want the data to be held on the parent side and pass the data into child component with props. Within the child component, you want to pass the input event back to parent for processing with $emit.

Changing the value with parent dropdown will update the value. Changing the value from within the child component's text input will as well. If you type in one, two or three, the parent select dropdown will be updated accordingly as well.

Comments

0

For you purpose you can use .sync modifier. https://v2.vuejs.org/v2/guide/components-custom-events.html#sync-Modifier

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.