1

I am following along the VueJS guide, and I am looking at https://v2.vuejs.org/v2/guide/components.html#Customizing-Component-v-model at the moment.

I tried to create a minimal example, but haven't been able to make it work.

What changes do I need to make so that the following two HTML statements are interchangeable as the VueJS guide suggests?:

<my-checkbox :checked="chicken" @change="val => { chicken = val }" value="A Bird"></my-checkbox>

and

<my-checkbox v-model="chicken" value="Chicken"></my-checkbox>

Here's the code I've got so far.

// Components#CustomizingComponentVModel
Vue.component('myCheckbox', {
  model: { prop: 'checked', emit: 'change' },
  props: ['value'],
  methods: {
    uVal: function(checkStatus) {
      this.$emit('change', checkStatus);
    }
  },
  template: '<span>' + 
              '<input type="checkbox" @change="uVal($event.target.checked)">' +
              '<label>{{ value }}</label>' + 
            '</span>'
});

// Default app
new Vue({
  el: '#app',
  data: function() {
    return { chicken: false };
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>

<!-- 
     I am trying to create a minimal example of customizing v-model described at
     https://v2.vuejs.org/v2/guide/components.html#Customizing-Component-v-model
-->

<div id="app">
  <my-checkbox :checked="chicken" @change="val => { chicken = val }" value="A Bird"></my-checkbox>
  <!-- VueJS guide suggest that previous line is same as the next one: -->
  <!-- <my-checkbox v-model="chicken" value="Chicken"></my-checkbox> -->
  <!-- If I comment line 9 and uncomment line 11, what changes do I need to make in my code to make this work? Also, why are those changes needed? -->
  <p>Chicken: {{ chicken }}</p>
</div>

2 Answers 2

1

You want to emit the input event instead of the change event, as explained in the documentation:

So for a component to work with v-model, it should (these can be configured in 2.2.0+):

  • accept a value prop
  • emit an input event with the new value

Alternatively, as hinted by the note in the parentheses, you can reconfigure your model to use the change event:

model: {
    prop: 'checked',
    event: 'change',
}

Below is a working example using the default model, emitting the input event:

Vue.component('myCheckbox', {
  props: ['value'],
  methods: {
    uVal: function(checkStatus) {
      this.$emit('input', checkStatus);
    }
  },
  template: '<span>' +
              '<input type="checkbox" @change="uVal($event.target.checked)">' +
              '<label>{{ value }}</label>' + 
            '</span>'
});

new Vue({
  el: '#app',
  data: {
    chicken: false,
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>
<div id="app">
  <my-checkbox v-model="chicken" value="Chicken"></my-checkbox>
  <p>Chicken: {{ chicken }}</p>
</div>

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

Comments

0

Never mind. I just answered my own question. It was merely a case of typo. The model should've read:

model: { prop: 'checked', event: 'change' }

instead of

model: { prop: 'checked', emit: 'change' }

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.