Noah Citron
Noah Citron

Reputation: 11

How to force vue to wait for async <script> to run before mounting components

I have an async js script which is loaded at the top of index.html in my vue project. This script exposes several functions into the window object which I would like to be able to call. I would like to be able to call these functions in the mounted() lifecycle hook, but the async function appears to complete only after mounted has finished. Is there a way I can force the vue instance to wait for all <script> to complete before mounting the root component?

Upvotes: 0

Views: 2502

Answers (2)

Naomi Messing
Naomi Messing

Reputation: 668

According to this issue in Github https://github.com/vuejs/vue/issues/7209 it seems that the async hooks in Vue lifecycle mounted() created() etc, is only for the ability to call async functions. but the lifecycle itself is synchronous.

Here are some ideas to manage this problem:

  1. You can wrap your component with v-if and render it just as soon as your data is ready.

  2. If you render a component by router - you can use the lifecycle of Vue router. and call your async function before enter to Vue page. do it like this:

    export default {
       beforeRouteEnter (to, from, next) {
           // called before the route that renders this component is confirmed.
           next()
       }
    }
    

this next() function calls the first Vue lifecycle hook...

full tutorial: https://router.vuejs.org/guide/advanced/navigation-guards.html#in-component-guards

Upvotes: 1

Noah Citron
Noah Citron

Reputation: 11

If anyone is interested, here is how I solved my problem:

I modified the js file that the <script> was referencing to set global.initComplete=false initially, and when the script was complete, I marked it as true.

For main.js file, I used:

import Vue from 'vue'
import App from './App.vue'

function init() {
    let vm = await new Vue({
        render: h => h(App),
    })
    if(!global.initComplete) {
        setTimeout(init, 50)
    } else {
        vm.$mount('#app')
    }
}
init()

Upvotes: 0

Related Questions