Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use 3rd party Javascript library in Vue component [duplicate]

I'm using Webpack and VueJs 2. I want to use a 3rd party javascript library in my component, such as this:

<script async defer src="https://apis.google.com/js/api.js" ... ></script>

I found an article here about how to do this for npm packages, but that doesn't work for me since this library is not available as npm package.

It's not possible for me to download the file locally and use it since the library might change and stop working. Therefore it has to be loaded from the link every time the page is loaded by the browser.

I found one possible solution here but that is basically a hack(modify dom to add a script element after document is loaded)

I believe there must be a simple good practice solution for this issue since I assume this is a common use-case.

Update: If I put the script inside head tags in my index file, it would be loaded for all the components. For performance reasons, I would want it to be loaded only for a certain component.

like image 612
Caner Avatar asked Mar 19 '18 14:03

Caner


2 Answers

As far as I know, there is no way you could use something better than adding the script tag into the head of your page dynamically. However, you could create a little plugin to handle that for you, and trigger the script loading only in the components you want, and just once.

Let's begin with the plugin itself:

import Vue from 'vue'

const scriptLoader = {
    loaded: [],
    load (src) {
        if (this.loaded.indexOf(src) !== -1) {
            return
        }

        this.loaded.push(src)

        if (document) {
            const script = document.createElement('script')
            script.setAttribute('src', src)
            document.head.appendChild(script)
        }
    }
}

Vue.use({
    install () {
        Vue.prototype.$scriptLoader = scriptLoader
    }
})

As you can see, you create an object scriptLoader that contains some sort of cache object loaded that will remember what script you already loaded at some point in your application. It also contains a load() method that will handle the adding of the script into your head.

The condition if (document) is here in case you would server side render your app, document would not exist.

You could then load your script into any of your component at creation using the created hook:

export default {
    ...
    created () {
        this.$scriptLoader.load('https://apis.google.com/js/api.js')
    }
}

This is the cleanest way I came with to handle that kind of script... I hope this can help...

like image 149
Hammerbot Avatar answered Oct 25 '22 04:10

Hammerbot


Ok, found a solution that satisfies all the requirements.

  • Script is downloaded from web, no npm package is needed
  • Script is only loaded for certain components when needed
  • No ugly dom-manipulation

Add the script inside index.html with v-if directive

<script v-if="loadGoogleAPI" async defer src="https://apis.google.com/js/api.js" ... ></script>

Inside the component file (.vue), if you want the script to be loaded set the flag to true:

<script>
export default {
  ...
  loadGoogleAPI: true,
  data() {
  ...
  }
};
</script>
like image 32
Caner Avatar answered Oct 25 '22 05:10

Caner