10
votes

Les références de Vue.js ne sont pas définies, même si ceci. $ Refs montre qu'elles sont là

J'ai une référence à un composant

  mapRef: VueComponent {_uid: 207, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}

En monté je fais ça, juste pour voir les objets sont disponibles

 mounted(){
   let self = this
   console.log(self.$refs) // Shows the mapRef object reference
   console.log(self.$refs.mapRef) // returns undefined ???
 }

self. $ refs montre ...

 <Gmap ref="mapRef">

Alors pourquoi self. $ Refs.mapRef renvoie undefined ?? Même si c'est clairement là ??


10 commentaires

Qu'en est-il du tout vieux this.$refs ?


Pouvez-vous créer un extrait de code ou un violon qui illustre le problème? Je ne peux pas le reproduire dans un extrait.


ceci. $ refs est la même chose. Donc non ... ça montre la même chose, Aussi ... non je ne peux pas non plus le reproduire dans JsFiddle. C'est juste dans mon projet que ça se passe. Ugh ... tellement frutstring


Notez que monté ne garantit pas que tous les composants enfants ont également été montés . docs


@ljubadr - en fait, selon cela, il attend. Pouvez-vous fournir un document pour soutenir votre déclaration?


J'ai fourni le lien, mais ici, c'est à nouveau des documents montés


donc l'article du média semble incorrect


Oui, vérifiez toujours les documents d'abord, a eu une expérience similaire avec des articles aléatoires


Au lieu de console.log() utilisez le debugger (ou placez un point d'arrêt) et inspectez les valeurs


Vous pouvez examiner cette question . console.log a quelques bizarreries


6 Réponses :


8
votes

J'ai rencontré un problème similaire pour obtenir une référence dans une instance de carte de dépliant, essayez d'attendre le "nextTick"

mounted(){
  this.$nextTick(()=>{
    let self = this
    console.log(self.$refs) // Shows the mapRef object reference
    console.log(self.$refs.mapRef) // returns undefined ???
  });
}

voir la documentation pour en savoir plus - https://vuejs.org/v2/api/#vm-nextTick et https://vuejs.org/v2/api/#mounted


4 commentaires

nah, retourne toujours undefined. Je suis perplexe :(


J'ai essayé jsFiddle. Et ça marche là-bas. Cela semble ne se produire que dans mon projet malheureusement. J'utilise le composant vue2-google-maps pour la carte. Alors peut-être que c'est quelque chose à voir avec le cycle de vie des composants particuliers ou quelque chose comme ça ?? Pas trop sûr.


J'ai regardé le repo vue2-google-maps, et il semble qu'un problème similaire ait été résolu avec nextTick étant la réponse principale, mais peut-être que certaines des réponses ici aideront - github.com/xkjyeah/vue-google-maps/issues / 260


Je l'ai résolu, le GMap référencé était à l'intérieur d'une instruction v-if. Je l'ai changé en v-show et cela fonctionne maintenant. Wierd que le console.log (this. $ Refs) l'a toujours montré comme "étant là" cependant.



10
votes

J'ai résolu ce problème en utilisant v-show au lieu de v-if.

J'avais le composant dans une instruction v-if.

<div v-show="!isLoading"> 
   <GMap ref="mapRef" />
 </div>

Je viens de changer ça en v-show

 <div v-if="!isLoading"> 
   <GMap ref="mapRef" />
 </div>

Et maintenant, l'objet est disponible dans mount (). Vous trouvez toujours étrange que console.log (this. $ Refs) ait montré qu'il était disponible comme clé sur ce. $ Refs, même si ce n'était pas le cas? C'est un comportement étrange.

L'autre chose étrange était que même si j'essayais d'accéder à ceci. $ Refs.mapRef dans ma section de chargement de données, APRÈS LE CHARGEMENT DES DONNÉES, (c'est-à-dire après isLoading = false), je ne pouvais toujours pas y accéder. Même si alors, il aurait dû être disponible car le v-if est passé.

Donc, v-show l'a résolu, en cachant simplement le div, au lieu de ne pas le rendre. Petite solution de contournement stupide.


0 commentaires

0
votes

Vous pouvez encapsuler votre fonction dans la méthode $mapPromise fournie par vue2-google-maps , qui garantira que la carte a été entièrement rendue avant d'exécuter votre code:

let self = this;
self.$refs.mapRef.$mapPromise.then(() => {
    console.log(self.$refs.mapRef);
})

Cela devrait résoudre tout problème où votre code repose sur le rendu complet de Google Map afin de fonctionner.

* REMARQUE: $mapPromise été nommé $mapCreated dans les versions précédentes.

Voir Docs: https://github.com/Jeson-gk/vue2-google-maps/blob/master/API.md#mapcreated--promisegooglemapsmap

-

La raison pour laquelle console.log(self.$refs); montrait la valeur quand vous avez regardé, est-ce que self.$refs est passé par référence. Ainsi, au moment où vous avez consulté la console, le reste des données a fini de se charger en quelques millisecondes. Et self.$ref.mapRef n'est pas passé par référence, il reste donc undefined , comme c'était le cas lors de l'exécution.

Essayez d'ajouter un point d'arrêt directement après console.log(self.$refs); et avant console.log(self.$refs.mapRef); et vous constaterez probablement que les données ne sont pas chargées.


0 commentaires

2
votes

Si aucune des méthodes ici ne fonctionne, vous voudrez vous assurer que votre composant n'est pas importé dynamiquement

Vous devrez toujours éviter d'encapsuler votre composant avec v-if et utiliser this.$refs.mapRef dans mounted()

Je n'utilisais pas le plugin / composant Vue Google Maps, mais mon propre composant personnalisé

Utilisation:

mounted(){
  setTimeout(()=>{
    this.$nextTick(()=>{
      this.$nextTick(()=>{
        console.log(this.$refs.mapRef) // returns undefined
      });
    });
  }, 0);
}

Au lieu de

 <div v-if="!isLoading"> 
   <GMap ref="mapRef" />
 </div>

Et puis utilisez this.$refs.mapRef dans monté, setTimeout() et this.$nextTick() n'est pas nécessaire

mounted(){
  console.log(this.$refs.mapRef) //works!
}

Les méthodes que j'ai essayées qui ne fonctionnaient toujours pas jusqu'à ce que j'arrête d'utiliser l'importation dynamique:

Je n'emballais pas avec v-if comme l'une des réponses mentionnées ici

export default {
  components: {
    CustomComponent: () => import('./CustomComponent'),
  },
  ...
}

J'ai déjà mis this.$refs.mapRef dans mounted() essayé de l'envelopper avec setTimeout() et 2 couches de this.$nextTick() .

Cela ne fonctionne que sur le rechargement à chaud, cesse de fonctionner sur l'actualisation de la page

import CustomComponent from './CustomComponent ';

export default {
  components: {
    CustomComponent,
  },
  ...
}

Merci à ce commentaire dans une autre réponse: Comment accéder à une méthode enfant depuis le parent dans vue.js


0 commentaires

0
votes

Dans mon cas, j'utilisais ref avec v-for, j'ai manqué le fait que ref n'est généré qu'après le rendu de v-for dans le dom, et j'utilisais v-for avec une propriété de tableau d'état qui est remplie quelques secondes après monté est appelé et j'essayais d'accéder à ma référence avant de remplir le tableau d'état.


0 commentaires

-1
votes

Vous pouvez l'utiliser comme suit, même si je ne sais pas si de toute façon cela pourrait interrompre l'implémentation dactylographiée pour les projets commerciaux.

(this as any).$refs.mapRef


0 commentaires