57

How do you bind a method result to a v-model with Vue.js?

example :

<someTag v-model="method_name(data_attribute)"></someTag>

I can't make it work for some reason.

Thank you.

5
  • 1
    Use a computed value for this. Commented Feb 4, 2016 at 20:32
  • 4
    That doesn't work because I can't pass a parameter to a computed property, I want the model to be evaluated with the attribute I'm passing. Edit: I'll try splitting things into components Commented Feb 4, 2016 at 20:37
  • 2
    If you can post a less obfuscated example maybe we could be of more assistance. It's unclear to me why you'd do it like this. Commented Feb 4, 2016 at 20:39
  • 2
    @greenymaster69 did you able to sort this issue? Commented Dec 12, 2018 at 13:34
  • 1
    You could wrap the component within another component and pass the data_attributes as a prop and use the computed set/get strategy as explained below. Commented Dec 23, 2019 at 19:22

3 Answers 3

61

Years later, with more experience, I found out that is it easier to bind :value instead of using v-model. Then you can handle the update by catching @change.

Edit (per request):

<input :value="myValue" @change="updateMyValue">

...

methods: {
  updateMyValue (event) {
    myValue = event.target.value.trim() // Formatting example
  }
}

And in a child component:

// ChildComponent.vue

<template>
  <button
    v-for="i in [1,2,3]">
    @click="$emit('change', i) />
</template>

// ParentComponent.vue

<template>
  <child-component @change="updateMyValue" />
</template>

<script>
import ChildComponent from './child-component'

export default {
  components: {
    ChildComponent
  },
  data () {
    return {
      myvalue: 0
    }
  },
  methods: {
    updateMyValue (newValue) {
      this.myvalue = newValue
    }
  }
}
</script>
Sign up to request clarification or add additional context in comments.

1 Comment

Always love to see people coming back to provide a valuable answer to their own question, very helpful!
44

v-model expressions must have a get and set function. For most variables this is pretty straight forward but you can also use a computed property to define them yourself like so:

data:function(){
    return { value: 5 }
},
computed: {
    doubleValue: {
        get(){
            //this function will determine what is displayed in the input
            return this.value*2;
        },
        set(newVal){
            //this function will run whenever the input changes
            this.value = newVal/2;
        }
    }
}

Then you can use <input v-model="doubleValue"></input>

if you just want the tag to display a method result, use <tag>{{method_name(data_attribute)}}</tag>

Comments

4

Agree with the :value and @change combination greenymaster. Even when we split the computed property in get/set, which is help, it seems very complicated to make it work if you require a parameter when you call for get(). My example is a medium sized dynamic object list, that populates a complex list of inputs, so:

  • I can't put a watch easily on a child element, unless I watch the entire parent list with deep, but it would require more complex function to determine which of the innter props and/or lists changed and do what fromthere
  • I can't use directly a method with v-model, since, it works for providing a 'get(param)' method (so to speak), but it does not have a 'set()' one
  • And the splitting of a computed property, have the same problem but inverse, having a 'set()' but not a 'get(param)'

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.