How to add vanilla .js to a custom Vue component

Costantin picture Costantin · Apr 28, 2017 · Viewed 7.2k times · Source

I'm trying to add a simple date-picker to a custom vue component. I'm not using webpack so I want to avoid ready made .vue components and I rather understand how to add simple javascript to vue.

I'm following this official vue tutorial

I've also seen this codepen but I can't manage to make the date picker appear.

This is my jsfiddle:

Html:

<div class="app">
  <datepicker id='date-elem'></datepicker>
</div>

app.js:

Vue.component('date-picker', {
  extends: Flatpickr,
  mounted () {
    this.Flatpickr(date-elem, {})}
})

How can I easily integrate vanilla js in a Vue component without the need of .vue files, webpack etc?

Answer

Bert picture Bert · Apr 28, 2017

So you have a few misconceptions here. To make this a component (a very basic component), this is how you might do it.

In Vue, you're not going to typically extend an external Javascript library. What you will typically make is called a wrapper component. Essentially, a Vue component that handles all the interaction with the external library. In this case you want to use Flatpickr. From the documentation, you need to use new Flatpickr(element, options). So we can do that in the mounted event, passing this.$el which will point to the root Vue component element.

Vue.component('date-picker', {
    template: "<input type='text'>",
    mounted () {
        new Flatpickr(this.$el, {})
    }
})

Here is your updated fiddle.

But this component doesn't do very much. It just allows you to pick a date. To allow that date to be used outside the component, we want to extend it to support v-model. Here's how you might do that.

Vue.component('date-picker', {
    props:["value"],
    data(){
        return {
            selectedDate: this.value
        }
    },
    template: "<input type='text' v-model='selectedDate' @input='onInput'>",
    methods:{
        onInput(){
            this.$emit('input', this.selectedDate)
        }
    },
    mounted () {
        new Flatpickr(this.$el, {})
    }
})

Now, you can use it like this.

<date-picker v-model="selectedDate"></date-picker>

And selectedDate will receive the date you pick.

Here is a fiddle showing that.