1

I have been trying to learn how Vue's v-model works with custom input and also regular input components.

I have seen examples where v-model is tied to a value in the component and also in the template and both of these values will be different. I find this very confusing and I think it may be a misunderstanding of "two way binding". How do you have an input tied to two values.

Example:

//v-model in template

const myCustomInput = ('my-custom-input', {
  data() {
    return {
      myObj: 'hello'
    }
  },
  template: `<input v-model="myObj" >`
});

//v-model in component

<my-custom-input v-model="someOtherObj.str">

I have seen examples of having two v-models like this with different values both defined at the template level and component.

However, when looking at this SO post, the answer by @asemahle seems a lot more logical. Furthermore the official Vue docs does not even have 2 separate v-models on the template and the component Vue JS component basics

In the latter examples, it seems a lot more logical as there is only one v-model defined and tied to the input component rather than two.

Is the first example incorrect? And if it's not can someone explain more clearly how that works. I can't seem to find any real good documents on having two separate v-models for one input.

tony19
  • 125,647
  • 18
  • 229
  • 307
henhen
  • 1,038
  • 3
  • 18
  • 36

4 Answers4

0

Two-way binding is referring to binding the template html to only one object. In your example you are trying to bind it to two separate values as you stated which is simply a misunderstanding of the term two-way binding.

In two-way binding you are still only going to bind one v-model to one data element. The 'Two-way" part refers to the fact that once the v-model is bound to a data property when you type into the text box, the data property also changes. ALSO if you change the data property, maybe through a method or API call, then the textbox will also reflect that data change, hence the two-way data binding.

Scornwell
  • 597
  • 4
  • 19
  • yes, that is what I thought as well, but I have seen too many examples online that have two `v-models` defined – henhen Sep 16 '19 at 15:25
  • 1
    Care to share an example? Maybe I can see where the post is going with it. If you had a v-model bound to two separate data properties, what would a textbox show if both those data properties had data in them? Would it concatenate them? If so, what would happen if you typed into a text-box bound to two data properties, both data properties would replicate the textbox. – Scornwell Sep 16 '19 at 15:28
0

In the example code you give, you have a component whose template includes a v-model on a native input:

template: `<input v-model="myObj" >`

That means that the input is (two-way) bound to myObj: changes to myObj's values will reflect in the input, and changes to the input will update the data item.

You then have an instance of that component with a v-model on it. The component will receive a value prop, and is expected to emit input events to achieve two-way binding. v-model on components is described here.

You do not have "an input tied to two values", but you might have a pointless binding, since the two things you bound are (apparently) unrelated. What you might want is for your component to act as a pass-through for the value, so that you can treat it almost like a native input. This example does that.

The custom input in the docs puts a v-model on the component and uses explicit binding for value and emit input from the native input element. You can replace those with a v-model to a settable computed, as I did in the example I linked in the paragraph above. The get returns value and the set performs the emit.

tony19
  • 125,647
  • 18
  • 229
  • 307
Roy J
  • 42,522
  • 10
  • 78
  • 102
  • That is pretty much what I wrote. I just wanted to confirm if having two v-models is correct as I see examples of this everywhere on the internet resources. But it seems like it is a misunderstanding derived from "two way binding" – henhen Sep 16 '19 at 15:54
  • Having any number of `v-models` can be correct, limited to one per entity that takes a value. – Roy J Sep 16 '19 at 16:07
  • what do you mean by having `any number of v-models`. If you mean having more than one `v-model` for the template and in the component, I think that is wrong and maybe a misunderstanding of two way binding as I stated in the op. I made custom input component following the official Vue JS docs and it seems to work very well. It will bind data properties regardless of which component it is coming from – henhen Sep 16 '19 at 16:27
  • A component could contain multiple entities that have `v-model` bindings. They do not have to be related to each other. Acting as a pass-through is a special use-case for `v-model`, and it still requires that they be bound to different variables. – Roy J Sep 16 '19 at 19:33
  • I've added a final paragraph to my answer to explain `v-model` as a pass-through. – Roy J Sep 16 '19 at 19:43
0

Try using watch in the child component
Parent:

<OptionCarouselCards                                                   
  :selected-values="bevarageSelected"
  @optionSelected="getBeverage"
/>

Child:

<v-slide-group
  v-model="selected"
  @change="onSelect"
>


export default {
  props: {
    selectedValues: {
      type: [Array, Number],
      required: false,
      default: -1
    } 
 },
 data () {
   return {
     selected: this.selectedValues
   }
 },
 watch: {
   selectedValues (selectedValues) {
     this.selected = selectedValues
 }
},
methods: {
  onSelect (event) {
    this.$emit('optionSelected', this.selected)
  }
 }
}
0

For multiple two way binding component arguments you can try something like this (vue 3):

<ChildComponent v-model:arg2="parentVariable1"  v-model:arg1="parentVariable2" />

And in the child component after changing value you have to just call:

this.$emit("update:arg1","some_value") 
or 
this.$emit("update:arg2","some_value_2") 

More details can be found in the vue docs

tony19
  • 125,647
  • 18
  • 229
  • 307
Tomek C.
  • 584
  • 9
  • 12