web-dev-qa-db-fra.com

Comment exécuter le code VueJS uniquement après que Vue soit complètement chargé et initialisé?

Je travaille sur un composant Vue qui sera placé sur plusieurs sites Web via un système de gestion de contenu. Le problème que je rencontre est que même si l'ordre de chargement des scripts js est correct, je reçois parfois l'erreur suivante:

Uncaught ReferenceError: Vue is not defined
    at HTMLDocument.<anonymous>

Vue est chargé via cdn et se trouve au-dessus du code du composant.

Tout le code Vue est exécuté comme ceci:

document.addEventListener("DOMContentLoaded", () => {
  // here is the Vue code
});

J'ai même ajouté un setTimeout () à l'intérieur de l'événement DOMContentLoaded et je n'ai toujours pas fait le tour. window.onload = function() n'a pas fonctionné non plus. J'ai toujours eu cette erreur de temps en temps. Les scripts sont chargés dans le corps.

Avez-vous une idée de ce que cela peut être une autre approche? Je veux être sûr qu'au moment où le code Vue est activé, Vue est chargé et prêt à être initialisé sur la page. Merci!

16
Bogdan Lungu

Utilisez l'événement de chargement pour attendre que le chargement de toutes les ressources soit terminé:

<script>
  window.addEventListener("load", function(event) {
    // here is the Vue code
  });
</script>

Explication complémentaire

DOMContentLoaded est un événement déclenché lorsque le code HTML est analysé, rendu et que DOM est construit. Il est généralement déclenché assez rapidement au cours de la vie de l'application. D'autre part, load n'est déclenché que lorsque toutes les ressources (images, feuilles de style, etc.) sont extraites du réseau et disponibles pour le navigateur.

Vous pouvez également utiliser l'événement de chargement pour un script spécifique .

18
Roy J

utilisez vue mounted() pour exécuter n'importe quel code au chargement de la page, et updated() pour s'exécuter après toute opération de composant. Une solution parfaite consisterait donc à combiner les deux Roy j et vue cycles de cycle de vie)

mounted() {
    window.addEventListener('load', () => {
         // run after everything is in-place
    })
},

// 99% using "mounted()" with the code above is enough, 
// but incase its not, you can also hook into "updated()"
//
// keep in mind that any code in here will re-run on each time the DOM change
updated() {
    // run something after dom has changed by vue
}

notez que vous pouvez omettre la window.addEventListener() et qu'elle continue à fonctionner, mais elle risque de manquer + si vous utilisez quelque chose comme jquery outerHeight(true) il vaut mieux l'utiliser à l'intérieur de l'événement window pour être sûr vous obtenez des valeurs correctes.

Mise à jour 1:

au lieu de window.addEventListener('load'), il existe aussi un autre moyen d’utiliser document.readyState pour que ce qui précède puisse être

mounted() {
  document.onreadystatechange = () => { 
    if (document.readyState == "complete") { 
        // run code here
    } 
  }
},

Mise à jour 2:

le moyen le plus fiable que j’ai trouvé jusqu’à présent consiste à utiliser debounce sur $nextTick.

import debounce from 'lodash/debounce'

// bad
updated() {
    this.$nextTick(debounce(() => {
        console.log('test') // runs multiple times
    }, 250)) // increase to ur needs
}

// good
updated: debounce(function () {
    this.$nextTick(() => {
        console.log('test') // runs only once
    })
}, 250) // increase to ur needs

lorsqu’on utilise debounce avec mis à jour cela devient délicat, alors assurez-vous de tester il b4 passe.

Mise à jour 3:

vous pouvez aussi essayer MutationObserver

36
ctf0