Home » vue » use instance property as v-model

use instance property as v-model

Posted by: admin November 26, 2021 Leave a comment

Questions:

I use a Form object to handle all my input fields and validation/errors etc.

new Vue({
el: '#root',
data: {
    form: { trainer: '' }
}

And I can use it as v-model like this:

<input v-model='form.trainer' name='trainer'>

I would like to make the form an instance property, because I have to pass it to all my components at the moment.

Vue.prototype.$form = {trainer: ''}
new Vue({ el: '#root' });

However, its not reactive anymore:

<input v-model="$form.trainer">
<span v-text="$form.trainer"></span>

Changes to the input are not reflected on the span.

Is there a solution to use a instance property as v-model?

Answers:

Using Global Mixin:

You can use Global Mixin and then add form: { trainer: '' } to it and then this option will be available in every Vue instance created afterwards like:

// inject a handler for `myOption` custom option
Vue.mixin({
  data: function () {
    return {
      form: { trainer: '' }
    }
  }
})

and then you can use it like normal component data option:

<input v-model="form.trainer">
<span v-text="form.trainer"></span>

Demo:

// inject a handler for `myOption` custom option
Vue.mixin({
  data: function() {
    return {
      form: { trainer: '' }
    }
  }
})

// Define a new component called trainer
Vue.component('trainer', {
  template: `<div>
    <input v-model="form.trainer">
    <span v-text="form.trainer"></span>
  </div>
  `
})

new Vue({
  el: "#myApp",
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
<div id="myApp">
  <trainer></trainer>
  <trainer></trainer>
</div>

Demo #2:

var trainer2Data = {
  form: { trainer: '' }
}

Vue.mixin({
  data: function() {
    return trainer2Data;
  }
})

// Define a new component called trainer2
Vue.component('trainer2', {
  template: `<div>
    <input v-model="form.trainer">
    <span v-text="form.trainer"></span>
  </div>
  `
})

new Vue({
  el: "#myApp",
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
<div id="myApp">
  <trainer2></trainer2>
  <trainer2></trainer2>
</div>