Loading an external script before loading components - Vue.js

Viewed 4133

In my Vue project, I would like to load a script from a server (e. g. https://myurl.com/API.js). The script contains a variable, which I would like to use in my Vue component (view). The problem is that when I load that scrip using the loadScript module:

import Vue from 'vue'
import LoadScript from 'vue-plugin-load-script';

Vue.use(LoadScript);
Vue.loadScript('https://quvia.cz:4443/portalAPI.js')

It is then loaded after the Vue component, so when try to console.log(externalScriptVariable), it is undefined. If I would setTimeout for 1 second, it would output the variable just fine.

What can I do in Vue.js to "await" the script loading, so it would load before every other Vue component?

3 Answers

You can use async/await

import Vue from 'vue'
import LoadScript from 'vue-plugin-load-script';

Vue.use(LoadScript);

(async function() {
  await Vue.loadScript('https://quvia.cz:4443/portalAPI.js');
  // other things after script loaded
})(); 

Or promise's then

import Vue from 'vue'
import LoadScript from 'vue-plugin-load-script';

Vue.use(LoadScript);

Vue.loadScript('https://quvia.cz:4443/portalAPI.js').then(() => {
  // other things after script loaded
})
.catch(() => {
  // error
});

What you could do is use the beforeCreate() lifecycle that vue provides and load the script from there.

import LoadScript from 'vue-plugin-load-script';

export default {
  name: "App",
  beforeCreate() {
    LoadScript('https://quvia.cz:4443/portalAPI.js')
  }
};

there are also other lifecycles that might suit your needs which you can find here: https://v2.vuejs.org/v2/guide/instance.html

Also, calling the LoadScript this in the main.js would make sure it is done before any components load

In my case, the problems were resolved by the "window" scope. Also, if you need to access any Vue element inside the "onload" function, you need a new variable for the "this" instance.

<script>
import { mapActions } from "vuex";
export default {
      name: "Payment",
      methods: {
        ...mapActions(["aVueAction"])
      },
      created() {
            let paywayScript = document.createElement("script");
            let self = this;
            paywayScript.onload = () => {
              // call to Vuex action.
              self.aVueAction();
              // call to script function
              window.payway.aScriptFunction();
            };
            // paywayScript.async = true;
            paywayScript.setAttribute(
              "src",
              "https://api.payway.com.au/rest/v1/payway.js"
            );
            document.body.appendChild(paywayScript);
      }
};
</script>

I worked with this on Vue 2.6.

Related