J'essaie d'obtenir l'élément canvas qui se trouve dans le modèle d'un composant. Nous avons trouvé d'excellentes documentations pour vuejs1, mais pas pour vuejs2, où "ref" est le seul moyen d'obtenir l'élément. Je reçois l'objet cependant, mais lorsque j'essaie d'accéder à la variable, il n'est pas défini.
Mon html
<div id="app>
<template id="image-capture">
<div class="row" >
<canvas ref="icanvas" ></canvas>
</div>
</template>
</div>
Mon js
const ic = {
template: '#image-capture' ,
created () {
console.log(this.$refs); //this returns object
console.log(this.$refs.icanvas); // but this is undefined
}
}
const routes = [
{ path: '/ic', component: ic},
]
const router = new VueRouter({
routes
})
new Vue({
router,
}).$mount('#app')
Je dois obtenir l'élément icanvas.
La created
est déclenchée avant le traitement du modèle.
Vous trouverez plus de détails ici: https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram
Vous devriez pouvoir accéder aux $ ref sur l’événement mounted
mounted: function() {
console.log(this.$refs.icanvas);
},
Vous pouvez utiliser la fonction $ nextTick (), le code contenu dans $ nextTick () sera exécuté après la mise à jour du DOM.
this.$nextTick(function () {
console.log(this.$refs.ANY_COMPONENT_REF)
})
j'ai eu exactement le même problème, dans mon cas je l'ai résolu en accédant à la référence dans la méthode qui modifie le v-if avec nextTick.
methods: {
open() {
this.show = true; //v-if condition
this.$nextTick(function() {
this.titleWidth = this.$refs.titleBg.clientWidth - 30;
});
}
Normalement, vous pouvez accéder à la référence mounted
, comme @Mihai Vilcu posté:
mounted: function() {
console.log(this.$refs.icanvas);
}
Cependant, comme l'a dit @BrownBe,
c'est toujours un problème si vos références sur un élément v-pour. Le DOM n'est pas en mesure d'accéder à cette référence lorsque le crochet monté est déclenché.
Jusqu'au 2018.10.27, la question était toujours d'actualité, et voici les derniers problèmes .
La raison peut être trouvée ici :
Une remarque importante sur le calendrier d’enregistrement des références: car les références elles-mêmes sont créées à la suite de la fonction de rendu, vous ne pouvez pas accédez-y au rendu initial - ils n’existent pas encore!
Et voici ce que je fais pour résoudre cette question:
mounted() {
this.$_xsl__watchRefs(this.$el, '.lazy_image').then(refs => {
//do something with `refs`
})
}
Et voici le $_xsl__watchRefs
$_xsl__watchRefs(targetNode, refsSelector) {
return new Promise(function(resolve) {
let observer = new MutationObserver(callback)
let config = { childList: true, subtree: true }
observer.observe(targetNode, config)
function callback(mutationsList, observer) {
mutationsList.forEach(mutation => {
if (mutation.type == 'childList') {
let refs = targetNode.querySelectorAll(refsSelector)
if (refs.length !== 0) {
observer.disconnect()
resolve(Array.from(refs))
}
}
})
}
})
}
Vous pouvez le modifier selon vos besoins. Voici MutationObserver qui supportait IE11 +.
Un autre choix facile. Supposons que vous utilisiez v-for
comme:
<li class="list__item" v-for="(item,index) in pubList" :key="index">
<img
class="list__img lazy_image"
ref="lazyImages"
>
</li>
Et
props: ['pubList'],
Dans ce cas, vous pouvez essayer:
watch: {
'pubList.length': function() {
this.$nextTick(function() {
console.log(this.$refs.lazyImages)
})
}
},
Dans certains cas, les deux méthodes ne fonctionneront pas car this.$refs.lazyImages
existait déjà. Donc, la méthode la plus sûre est:
mounted() {
if (this.$refs.lazyImages) {
//do something with `this.$refs.lazyImages`
} else {
this.$_xsl__watchRefs(this.$el, '.lazy_image').then(refs => {
//do something with `refs`
})
}
},