Comment référencer le texte présent dans Vue.js?
Vue.component('component', {
template: `<button><slot></slot></button>`,
created: function() {
// i would like to access the text in slot here
}
});
Le contenu à l'intérieur de l'emplacement par défaut, qui correspond à ce que vous décrivez, est présenté sous la forme this.$slots.default
dans Vue. Ainsi, le moyen le plus naïf d’obtenir le texte à l’intérieur de votre bouton serait d’utiliser this.$slots.default[0].text
.
Vue.component('component', {
template: `<button><slot></slot></button>`,
created: function() {
const buttonText = this.$slots.default[0].text;
}
});
Le problème est qu’il peut y avoir plus d’un nœud à l’intérieur de la fente et que ceux-ci ne sont pas nécessairement du texte. Considérez ce bouton:
<button><i class="fa fa-check"></i> OK</button>
Dans ce cas, l’utilisation de la première solution donnera undefined
car le premier nœud de l’emplacement n’est pas un nœud de texte.
Pour résoudre ce problème, nous pouvons emprunter une fonction de la documentation Vue pour les fonctions de rendu.
var getChildrenTextContent = function (children) { return children.map(function (node) { return node.children ? getChildrenTextContent(node.children) : node.text }).join('') }
Et écrire
Vue.component("mybutton", {
template:"<button><slot></slot></button>",
created(){
const text = getChildrenTextContent(this.$slots.default);
console.log(text)
}
})
Ce qui retournera tout le texte dans la fente jointe. En supposant que l'exemple ci-dessus avec l'icône, il renvoie "OK".
J'utilise "ref" :
<span ref="mySlot">
this.$refs.mySlot.innerHTML
Attention: <slot ref="refName"></slot>
ne fonctionne pas car <slot>
ne sont pas rendus en HTML. Vous devez envelopper le <slot></slot>
avec <div></div>
ou <span></span>
Vue.component('component', {
template: '<button>' +
'<span ref="mySlot">' +
'Text before<br />' +
'<slot name="slot1">' +
'Text by default' +
'</slot>' +
'<br />Text after' +
'</span>' +
'</button>',
mounted: function() {
console.log( this.$refs.mySlot.innerHTML);
}
});
new Vue({
el: '#app'
});
<script src="https://vuejs.org/js/vue.min.js"></script>
<div id="app">
<component>
<span slot="slot1">I'm overriding the slot and text appear in this.$refs.mySlot.innerHTML !</span>
</component>
</div>
Vous pouvez accéder au texte de l'emplacement en joignant le texte innerText de tous les enfants qu'il contient.
getSlotText() {
return this.$slots.default.map(vnode => (vnode.text || vnode.Elm.innerText)).join('');
},