Comprendre les composants sans rendu dans Vue

Dans cet article, nous allons apprendre à créer des composants sans rendu dans Vue, et comment et quand les utiliser.
Les composants sans rendu sont des composants qui ne génèrent aucun type de HTML dans le DOM par eux-mêmes. Ils sont très uniques, car ils servent d'encapsuleurs logiques que vous pouvez insérer dans votre modèle et leur transmettre un élément HTML personnalisé. Ils exécuteront leur logique et l'injecteront dans votre HTML via quelque chose appelé une portée.
Dans cet article, nous allons apprendre comment créer des composants sans rendu dans Vue, et comment et quand les utiliser. Sachez qu'en raison de la portée (hah!) De l'article, je devrai supposer que vous avez des connaissances de base sur les slots Vue et les slots scoped.
Si vous avez besoin d'un rappel sur les slots scoped, vous pouvez consulter le documentation pour les emplacements étendus ici ou jetez un œil à ces articles de blog sur Vue slots et Vue scoped slots .
Quand utiliser des composants sans rendu? [19659006] Si jamais vous vous trouvez en train d'écrire un composant qui a une logique particulière à l'intérieur de celui-ci, mais que vous souhaitez que l'utilisateur de ce composant puisse écrire n'importe quel HTML personnalisé pour lui et utiliser cette logique, alors les composants sans rendu pourraient être l'une de vos solutions
Notez que j'ai dit une de vos solutions car cela peut aussi être réalisé en écrivant un mixin, ou même une classe ou une fonction JS standard qui injecte ce comportement dans vos composants. En fait, je dirais que la plupart du temps, une approche fonctionnelle sera supérieure de quelque manière que ce soit – pensez en termes de Vue 3 et de l'API de composition, du code réutilisable et encapsulé qui peut être injecté et utilisé dans n'importe lequel de vos composants.
Concernant les mixins en particulier, rappelez-vous qu'ils présentent l'inconvénient d'une collision potentielle avec d'autres parties de votre composant. Par rapport à cet inconvénient particulier, les composants sans rendu ont l'avantage en raison de leur encapsulation de la logique.
Maintenant, cela dit, il existe des scénarios où vous voudrez peut-être aborder le problème avec un composant sans rendu simplement parce que vous voulez afficher ce comportement dans le DOM, ou parce que vous écrivez une bibliothèque de composants qui doit être super flexible.
Dans cet article, nous allons regarder un exemple de base qui illustrera ce dernier scénario. Imaginez que vous écrivez un composant qui a la capacité de trier un tableau d'objets par une propriété particulière – mais vous ne voulez pas être strict sur la façon dont ce contenu doit être rendu.
Peut-être que l'utilisateur veut le mettre dans un
- ou peut-être même faire un
. Dans ce cas, un composant sans rendu peut être une bonne solution. Construire le composant sans rendu
Pour commencer avec un composant sans rendu, examinons la configuration la plus basique possible, et comment nous pourrions l'utiliser sur un autre
Un composant sans rendu n'a pas de car il ne produit rien dans le DOM. Il possède cependant une fonction de rendu qui expose un seul emplacement à portée. De cette façon, tout ce que nous lançons sera rendu dans le modèle du parent – comportement normal des emplacements. Tout d’abord, créons notre composant de classement de liste sans rendu. Nous allons l'appeler OrderedObjects parce que cela me prend sérieusement plus de temps pour nommer les choses que pour écrire le code réel et je viens d'abandonner et de le nommer ainsi – veuillez rester avec moi. #developerlife
# OrderedObjects.vue
< script >
export default {
render () {
return this ]. $ scopedSlots . default ( {} ) ;
}
} ;
</ script >
Comme je l'ai déjà mentionné, la seule vraie exigence ici est que nous retournions un seul scopedSlot, par défaut. Le {} dans la fonction est l'endroit où nous allons exposer les données au parent plus tard, mais ne vous inquiétez pas pour le moment.
Revenons à App.vue ou à l'endroit où vous mettez vos composants réels , et utilisez ce composant. N'oubliez pas de l'importer et de l'ajouter aux composants: {} d'abord!
# App.vue
< modèle >
< div id = " app " >
< OrderedObjects > Bonjour! </ OrderedObjects >
</ div >
</ modèle >
< script >
import OrderedObjects from "./ components / OrderedObjects" ;
export default {
composants : {
OrderedObjects
}
} ;
</ script >
Si vous exécutez ce code sur votre navigateur en ce moment, vous ne verrez que le message Hi! chaîne en sortie dans la chaîne, ce qui signifie que le scopedSlot fait son travail!
Ensuite, créons des données factices avec lesquelles jouer et transmettons-les à OrderedObjects. Nous allons d'abord créer les données dans App.vue.
# App.vue
< modèle >
< div id = " app " >
< OrderedObjects : objects = " stuffs " > Bonjour! </ OrderedObjects >
</ div >
</ modèle >
< script >
import OrderedObjects from "./ components / OrderedObjects" ;
export default {
composants : {
OrderedObjects
}
données () {
return {
stuffs : [
{ nom : "some" importance : 2 } ,
{ nom : "stuffs" importance : 1 }
{ nom : "et" importance : 1 }
{ nom : "choses" importance : 0 }
{ nom : "Goku" importance : 9001 }
]
} ;
}
} ;
</ script >
Tout d'abord, nous avons ajouté des éléments à l'objet data () de notre parent et y avons introduit des données factices. Enfin, assurez-vous d'ajouter: objects = "stuffs" à l'élément OrderedObjects réel du modèle. Nous allons créer immédiatement un objet de propriété à l'intérieur.
# OrderedObjects.vue
< script >
export par défaut {
accessoires : {
objets : { type : Array required : true }
} [19659025] render () {
return this . $ scopedSlots . default ( { ]} ) ;
}
} ;
</ script >
Maintenant que nous avons ajouté un accessoire d'objets à notre composant OrderedObjects, nous pouvons en faire un certain usage. Ce composant est censé commander les choses pour nous, mais pour l'instant, retournons simplement la liste au parent telle qu'elle nous a été donnée.
Ajoutez la propriété objects à l'objet scopedSlot comme suit.
# OrderedObjects. vue
< script >
export par défaut {
accessoires : {
objets : { type : Array required : true }
} [19659025] render () {
return this . $ scopedSlots . default ( { ]
objets : this . objets
} ) ;
}
} ;
</ script >
Si vous vérifiez votre navigateur maintenant, rien n'aura encore changé. C'est parce que nous n'avons pas encore utilisé nos données exposées sur notre parent. Revenons à App.vue et apportons les modifications suivantes.
# App.vue
< modèle >
< div id = " app " >
< OrderedObjects : objects = " stuffs " >
< template v-slot: default = " {objects} " >
< ul >
< li v-for = " obj in objects " : key = " nom.obj " >
{{obj.importance}} - {{obj.name}}
</ li >
</ ul >
</ modèle >
</ OrderedObjects >
</ div >
</ template >
Si vous revenez à votre navigateur, vous devriez voir que maintenant nous avons une liste d'éléments affichés à l'écran. Vous vous souvenez de cet objet que nous avons transmis avec la propriété objects dans notre fonction render dans la dernière partie?
{
objets: this.objects
}
C'est exactement ce que nous récupérons de l'emplacement de portée de cette ligne, l'objet avec la clé des objets. Nous utilisons ensuite déstructuration JavaScript à pour le décompresser .
< template v-slot: default = " {objets} " >
Pour le moment, nous ne faisons pas grand-chose à l'intérieur de OrderedObjects avec nos données, et le simple fait de les renvoyer semble être une opportunité gâchée , comme avoir 🥑 sans toast. Modifions donc notre composant pour réorganiser nos données par nom.
# OrderedObjects.vue
< script >
export par défaut {
accessoires : {
objets : { type : Array required : true }
} [19659025] render () {
return this . $ scopedSlots . default ( { ]
objets : this . ordersObjs
} ) ;
}
calculé : {
ordersObjs () {
const objs = [ ... this . objets ] ;
return objs . sort ( ( a b ) => {
if ( a . name . toLowerCase ( ]) > b . nom . toLowerCase () ) return 1 ;
if ( a . name . toLowerCase () < b . ] name . toLowerCase () ) return - 1 ;
return 0 ;
} ) ;
}
} [19659039]} ;
</ script >
Ce que nous avons fait ici, c'est d'abord créer une propriété calculée appelée commandObjs. À l'intérieur de cette propriété calculée, nous faisons une copie du tableau this.objects (si vous sautez cette étape, vous allez modifier le prop, qui est un gros NON!).
Nous appliquons ensuite une fonction de tri à la copie de le tableau qui évalue simplement la propriété name et organise l'ordre des éléments.
Enfin, nous utilisons cette nouvelle propriété calculée dans notre fonction de rendu. Au lieu de passer dans la zone de portée du prop this.objects, nous renvoyons this.orderedObjs.
Vérifiez votre navigateur maintenant, et vous devriez voir que les données de la liste sont maintenant classées par nom!
Maintenant que vous savez comment créer un composant sans rendu et comment cela fonctionne, créons une deuxième façon de rendre cette liste afin que l'utilité réelle de ces composants soit mieux présentée.
Revenez sur App.vue et ajoutez le code suivant: [19659019] # App.vue
< modèle >
< div id = " app " >
< OrderedObjects : objects = " stuffs " >
< template v-slot: default = " {objects} " >
< ul >
< li v-for = " obj in objects " : key = " nom.obj " > {{import.obj}} – {{nom.obj}} </ li >
</ ul >
</ modèle >
</ OrderedObjects >
< OrderedObjects : objects = " stuffs " >
< template v-slot: default = " {objects} " >
< tableau >
< tr v-for = " obj in objects " : key = " nom_obj " >
< td > {{obj.importance}} </ td >
< td > {{obj.name}} </ td >
</ tr >
</ tableau >
</ modèle >
</ OrderedObjects >
</ div >
</ template >
Notez la deuxième utilisation de OrderedObjects. Nous y introduisons exactement les mêmes données, le tableau stuffs dans la propriété objects. Cependant, notez que cette fois, nous allons afficher nos données dans une table (🤢 je sais).
Grâce à la puissance des créneaux horaires et au traitement des données que notre composant sans rendu encapsule, nous pouvons maintenant avoir un composant d'encapsulation qui modifie, analyse ou même atteint une API pour que nous puissions analyser les données. Le tout avec la flexibilité de permettre aux utilisateurs de ce composant de transmettre leur propre HTML pour afficher les résultats comme bon leur semble!
Le code de cet article se trouve sur le sandbox suivant: https: // codesandbox .io / s / renderless-components-prqmt
Récapitulation
Les composants sans rendu ne sont qu'une façon de réaliser une encapsulation de code partageable ou réutilisable. Ils résolvent la problématique spécifique de vouloir avoir cette capacité de partage directement sur votre modèle, mais peuvent également être remplacés via les solutions discutées au début de ce chapitre.
Quoi qu'il en soit, c'est un excellent outil pour connaître (et comprendre!) dans la ceinture d'outils Vue!
Comme toujours, merci de lire et de partager avec moi vos expériences de composants sans rendu sur Twitter à: @marinamosti .
PS Tous saluent l'avocat magique! 🥑
P.P.S. ❤️🔥🐶☠️
Source link