Search code examples
javascriptvue.jscomponentsvuejs2

Wrap a VueJs component


I'm using a third party datepicker component. I created a wrapper for this component so I can set some defaults that fit my application. However, I'm having problems passing the model. How can I ensure the two-way binding for my model? When I use the third party component directly, everything works.

my-page.vue

<my-datepicker v-model="from"></my-datepicker>

my-datepicker.vue

<template>
  <thirdparty-datepicker>
    :value="value"
  </thirdparty-datepicker>
</template>
<script>
  export default {
    props: {
      value: {
        value: String
      }
    }
  }
</script>

EDIT

Based on the input from Bert I managed to get it to work. Every time the date changed on the third party component an input event was thrown. All there was to do was hookup to that event and re-emit it.

<template>
  <thirdparty-datepicker>
    :value="value"
    v-on:input="change"
  </thirdparty-datepicker>
</template>
<script>
  export default {
    props: {
      value: {
        value: String
      }
    },
    methods: {
      change (newValue) {
        this.$emit('input', newValue)
      }
    }
  }
</script>

Solution

  • In order to support v-model on your custom component you have to accept a value parameter and emit an input event (though that can be customized; see the link for details). Your code is only doing part of that. How you implement that is going to depend on how the third party component works.

    Let's say that the third party component emitted a change event. If it did, then you would emit input when the third party component emitted change.

    <template>
      <thirdparty-datepicker :value="value" @change="onChange">    
      </thirdparty-datepicker>
    </template>
    <script>
      export default {
        props: {
          value: {
            value: String
          }
        },
        methods:{
          onChange(newValue){
            this.$emit('input', newValue)
          }
        }
      }
    </script>