tyteen4a03
tyteen4a03

Reputation: 1932

Vue.js two-way data binding with v-model

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.

Upvotes: 1

Views: 2953

Answers (3)

Harshal Patil
Harshal Patil

Reputation: 20950

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.

Upvotes: 2

Vsevolod Fedorov
Vsevolod Fedorov

Reputation: 521

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

Upvotes: 0

josephting
josephting

Reputation: 2665

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.

Upvotes: 2

Related Questions