Nouvelles intéressantes Vue 3

Au lieu de l'avant-propos


Vue est utilisé dans tous les projets FunCorp. Nous suivons de près l'évolution du cadre, améliorons constamment le processus de développement et mettons en œuvre les meilleures pratiques. Et, bien sûr, nous ne pouvions pas passer à côté et ne pas traduire l'article de Philip Rakovsky, co-fondateur de VueStorefront, sur les nouvelles fonctionnalités de Vue 3 qui affectent sérieusement l'écriture de code.

image
La dernière fois, nous avons examiné les fonctionnalités qui affectent les performances de Vue 3 . Nous savons déjà que les applications écrites sur la nouvelle version du framework fonctionnent très rapidement, mais les performances ne sont pas le changement le plus important. Pour la plupart des développeurs, la façon dont Vue 3 affecte la façon dont vous écrivez du code est beaucoup plus importante.

Comme vous l'avez peut-être deviné, Vue 3 aura beaucoup de fonctionnalités intéressantes. Heureusement, l'équipe Vue a ajouté plus d'améliorations et d'ajouts que de changements de rupture. Pour cette raison, la plupart des développeurs qui connaissent Vue 2 devraient rapidement se familiariser avec la nouvelle syntaxe.

Commençons par une API dont beaucoup d'entre vous ont peut-être entendu parler.

API de composition


L'API Composition est la fonctionnalité la plus discutée et la plus mentionnée de la prochaine version majeure de Vue. La syntaxe de l'API Composition fournit une approche complètement nouvelle de l'organisation et de la réutilisation du code.

Nous créons maintenant des composants avec une syntaxe appelée API Options. Afin d'ajouter de la logique, nous créons des propriétés (options) dans l'objet composant, par exemple des données, des méthodes, des calculs, etc. Le principal inconvénient de cette approche est qu'elle n'est pas du code JavaScript en tant que tel. Vous devez savoir exactement quelles options sont disponibles dans le modèle et à quoi cela ressemblera. Le compilateur Vue convertit les propriétés en code JavaScript fonctionnel pour vous. En raison de cette fonctionnalité, nous ne pouvons pas utiliser complètement l'auto-complétion ou la vérification de type.

L'API Composition résout ce problème et permet d'utiliser les mécanismes disponibles via les options utilisant des fonctions JavaScript ordinaires.
L'équipe Vue décrit l'API Composition comme «une API optionnelle basée sur des fonctionnalités qui permet une utilisation flexible de la composition dans la logique des composants». Le code écrit à l'aide de la nouvelle API est plus facile à lire, ce qui le rend plus facile à comprendre.

Pour comprendre le fonctionnement de la nouvelle syntaxe, considérons un exemple de composant simple.

<template> <button @click="increment"> Count is: {{ count }}, double is {{ double }}, click to increment. </button> </template> <script> import { ref, computed, onMounted } from 'vue' export default { setup() { const count = ref(0) const double = computed(() => count.value * 2) function increment() { count.value++ } onMounted(() => console.log('component mounted!')) return { count, double, increment } } } </script> 

Nous allons diviser le code en plusieurs parties et analyser ce qui se passe ici.

 import { ref, computed, onMounted } from 'vue' 

Comme je l'ai mentionné ci-dessus, l'API Composition présente les options des composants comme des fonctions, donc, tout d'abord, nous devons importer les fonctions nécessaires. Dans cet exemple, nous devons créer une propriété réactive en utilisant ref calculé en utilisant calculé et accéder au hook de cycle de vie monté à l'aide de la fonction onMounted.

Vous avez peut-être une question: quelle est cette mystérieuse méthode de configuration?

 export default { setup() {} } 

En bref, l'installation n'est qu'une fonction qui transmet des propriétés et des fonctions à un modèle. Nous décrivons toutes les propriétés réactives et calculées, les crochets de cycle de vie et tous les observateurs dans la fonction de configuration, puis les renvoyons pour les utiliser dans le modèle.

Au fait que nous ne reviendrons pas de la configuration, il n'y aura pas d'accès dans le modèle.

 const count = ref(0) 

La propriété réactive de comptage est initialisée à l'aide de la fonction ref. Il prend une primitive ou un objet et renvoie un lien réactif. La valeur transmise sera stockée dans la propriété value du lien créé. Par exemple, si nous voulons accéder à la valeur de count, nous devons accéder explicitement à count.value.

 const double = computed(() => count.value * 2) function increment() { count.value++ } 

Nous déclarons donc une double propriété calculée et une fonction d'incrémentation.

 onMounted(() => console.log('component mounted!')) 

À l'aide du crochet onMounted, nous imprimons un message à la console après avoir monté le composant pour démontrer cette possibilité.

 return { count, double, increment } 

Pour que les propriétés count et double et la méthode increment soient disponibles dans le modèle, nous les renvoyons depuis la méthode setup.

 <template> <button @click="increment"> Count is: {{ count }}, double is {{ double }}. Click to increment. </button> </template> 

Et le tour est joué! Nous avons accès aux propriétés et méthodes de la configuration, comme si elles avaient été déclarées via l'ancienne API Options.

Il s'agit d'un exemple simple, similaire pourrait facilement être écrit à l'aide de l'API Options.
Mais l'avantage de la nouvelle API de composition n'est pas tant dans la possibilité d'écrire du code dans un style différent, mais dans les possibilités ouvertes pour la réutilisation de la logique.

Réutilisation du code avec l'API Composition


Examinons de plus près les avantages de la nouvelle API Composition, par exemple, pour la réutilisation de code. Maintenant, si nous voulons utiliser un morceau de code dans plusieurs composants, nous avons deux options: les mixins et les emplacements de portée. Les deux options ont leurs inconvénients.

Nous voulons extraire la fonctionnalité du compteur et la réutiliser dans d'autres composants. Voici un exemple de la façon dont cela peut être fait en utilisant l'existant et en utilisant la nouvelle API.

Pour commencer, considérez l'implémentation à l'aide de mixins.

 import CounterMixin from './mixins/counter' export default { mixins: [CounterMixin] } 

Le plus gros problème avec cette approche est que nous ne savons rien de ce qui est ajouté à notre composant. Cela rend la compréhension difficile et peut conduire à des conflits avec les propriétés et méthodes existantes.

Considérez maintenant les emplacements avec une portée limitée.

 <template> <Counter v-slot="{ count, increment }"> {{ count }} <button @click="increment">Increment</button> </Counter> </template> 

Lorsque vous utilisez des emplacements, nous savons exactement à quelles propriétés nous avons accès via la directive v-slot, qui est assez simple à comprendre. L'inconvénient de cette approche est que nous ne pouvons accéder qu'aux données du composant Counter.

Considérons maintenant une implémentation utilisant l'API Composition.

 function useCounter() { const count = ref(0) function increment () { count.value++ } return { count, incrememt } } export default { setup () { const { count, increment } = useCounter() return { count, increment } } } 

Il a l'air beaucoup plus élégant, non? Nous ne sommes pas limités par un modèle ou une étendue, et nous savons exactement quelles propriétés de compteur sont disponibles. Et du fait que useCounter n'est qu'une fonction qui renvoie des données, un bonus agréable nous permet de terminer le code dans l'éditeur. Il n'y a pas de magie ici, donc l'éditeur peut nous aider avec la vérification de type et donner des conseils.

L'utilisation de bibliothèques tierces semble également meilleure. Par exemple, si nous voulons utiliser Vuex, nous pouvons importer explicitement la fonction useStore et ne pas obstruer le prototype Vue avec cette propriété. $ Store. Cette approche vous permet de vous débarrasser des manipulations supplémentaires dans les plugins.

 const { commit, dispatch } = useStore() 

Si vous souhaitez en savoir plus sur l'API Composition et ses applications, je vous recommande de lire un document dans lequel l'équipe Vue explique les raisons de la création d'une nouvelle API et propose des cas dans lesquels elle sera utile. Il existe également un magnifique référentiel avec des exemples d'utilisation de l'API Composition de Thorsten Lünborg, l'un des membres de l'équipe de base de Vue.

Changements de configuration et de montage


Il y a d'autres changements importants dans la nouvelle Vue dans la façon dont nous construisons et configurons notre application. Regardons un exemple.

 import Vue from 'vue' import App from './App.vue' Vue.config.ignoredElements = [/^app-/] Vue.use(/* ... */) Vue.mixin(/* ... */) Vue.component(/* ... */) Vue.directive(/* ... */) new Vue({ render: h => h(App) }).$mount('#app') 

Nous utilisons maintenant l'objet global Vue pour configurer et créer de nouvelles instances de Vue. Toute modification que nous apportons à l'objet Vue affectera les instances et composants finaux.

Voyons comment cela fonctionnera dans Vue 3.

 import { createApp } from 'vue' import App from './App.vue' const app = createApp(App) app.config.ignoredElements = [/^app-/] app.use(/* ... */) app.mixin(/* ... */) app.component(/* ... */) app.directive(/* ... */) app.mount('#app') 

Comme vous l'avez déjà remarqué, la configuration fait référence à une instance de Vue spécifique créée à l'aide de createApp.

Cela rend notre code plus lisible, réduit les risques de problèmes inattendus avec des plugins tiers. Maintenant, toute bibliothèque tierce qui modifie l'objet global Vue peut affecter votre application dans un endroit inattendu (surtout s'il s'agit d'un mixage global), ce qui est impossible dans Vue 3.

Ces changements sont discutés dans le RFC, et peut-être à l'avenir la mise en œuvre sera différente.

Fragments


Une autre fonctionnalité intéressante sur laquelle nous pouvons compter dans Vue 3.
Quels sont les fragments?
Actuellement, un composant ne peut avoir qu'un seul élément racine, ce qui signifie que le code ci-dessous ne fonctionnera pas.

 <template> <div>Hello</div> <div>World</div> </template> 

La raison en est que l'instance Vue qui se cache derrière chaque composant ne peut être attachée qu'à un seul élément DOM. Il existe maintenant un moyen de créer un composant avec plusieurs éléments racine: pour cela, vous devez écrire un composant dans un style fonctionnel qui n'a pas besoin de sa propre instance de Vue.

Il s'avère que le même problème existe dans la communauté React, il a été résolu en utilisant l'élément Fragment virtuel.

Cela ressemble à ceci:

 class Columns extends React.Component { render() { return ( <React.Fragment> <td>Hello</td> <td>World</td> </React.Fragment> ); } } 

Malgré le fait que Fragment ressemble à un élément DOM normal, il est virtuel et ne sera pas créé dans l'arborescence DOM. Avec cette approche, nous pouvons utiliser la fonctionnalité d'un seul élément racine sans créer un élément supplémentaire dans le DOM.

Vous pouvez maintenant utiliser des fragments dans Vue 2, mais en utilisant la bibliothèque vue-fragments, et dans Vue 3, ils fonctionneront prêts à l'emploi!

Suspense


Une autre excellente idée de l'écosystème React qui sera implémentée dans Vue 3 est Suspense.

Suspense suspend le rendu du composant et affiche un stub jusqu'à ce que certaines conditions soient remplies. À Vue London, Ewan Yu a effleuré Suspense avec désinvolture et a révélé l'API que nous pouvons attendre à l'avenir. Le composant Suspense aura 2 emplacements: pour le contenu et pour le talon.

 <Suspense> <template > <Suspended-component /> </template> <template #fallback> Loading... </template> </Suspense> 

Le stub sera affiché jusqu'à ce que le composant <Suspended-component /> soit prêt. Le composant Suspense peut également s'attendre à charger le composant asynchrone ou à effectuer certaines actions asynchrones dans la fonction de configuration.

Plusieurs modèles en V


v-model est une directive avec laquelle vous pouvez utiliser une liaison bidirectionnelle. Nous pouvons transmettre la propriété réactive et la modifier à l'intérieur du composant.

Nous sommes bien connus pour travailler avec des éléments de formulaire.

 <input v-model="property" /> 

Mais saviez-vous que le modèle v peut être utilisé avec n'importe quel composant? Sous le capot, le modèle v ne fait que transmettre le paramètre de valeur et écouter l'événement d'entrée.

Vous pouvez réécrire l'exemple précédent en utilisant cette syntaxe comme suit:

 <input v-bind:value="property" v-on:input="property = $event.target.value" /> 

Vous pouvez même modifier les noms de propriété et les événements par défaut à l'aide de l'option de modèle:

 model: { prop: 'checked', event: 'change' } 

Comme vous pouvez le voir, la directive v-model peut être un «sucre syntaxique» très utile si nous voulons utiliser la liaison bidirectionnelle dans nos composants. Malheureusement, il ne peut y avoir qu'un seul modèle en V par composant.

Heureusement, dans Vue 3, ce problème sera résolu. Nous pouvons transmettre le nom à v-model et utiliser autant de v-model que nécessaire.

Exemple d'utilisation:

 <InviteeForm v-model:name="inviteeName" v-model:email="inviteeEmail" /> 

Ces changements sont discutés dans le RFC, et peut-être à l'avenir la mise en œuvre sera différente.

Portails


Les portails sont des composants créés pour rendre le contenu en dehors de la hiérarchie du composant actuel. C'est également l'une des fonctionnalités implémentées dans React . Dans la documentation de React, les portails sont décrits comme suit: "Les portails vous permettent de rendre des enfants dans un nœud DOM qui est en dehors de la hiérarchie DOM du composant parent."

Les portails sont parfaits pour implémenter des composants tels que les fenêtres modales, les fenêtres contextuelles et tous ceux qui doivent être affichés en haut de la page.

Lorsque vous utilisez des portails, vous pouvez être sûr que les styles du composant parent n'affecteront pas le composant enfant. Il vous permettra également d'économiser des hacks z-index sales.

Pour chaque portail, nous devons spécifier la destination dans laquelle le contenu du portail doit être affiché.

Ce qui suit est une option d'implémentation de la bibliothèque portal-vue, qui ajoute des portails à Vue 2.

 <portal to="destination"> <p>This slot content will be rendered wherever the portal-target with name 'destination' is located.</p> </portal> <portal-target name="destination"> <!-- This component can be located anywhere in your App. The slot content of the above portal component wilbe rendered here. --> </portal-target> 

Et dans Vue 3, cette fonctionnalité sera prête à l'emploi.

Nouvelle API de directive personnalisée


L'API de directive personnalisée changera un peu dans Vue 3 pour mieux correspondre au cycle de vie du composant. La création de directives deviendra plus intuitive et donc plus facile à comprendre et à apprendre pour les débutants.

Maintenant, la déclaration de la directive utilisateur ressemble à ceci:

 const MyDirective = { bind(el, binding, vnode, prevVnode) {}, inserted() {}, update() {}, componentUpdated() {}, unbind() {} } 

Et dans Vue 3, cela ressemblera à ceci:

 const MyDirective = { beforeMount(el, binding, vnode, prevVnode) {}, mounted() {}, beforeUpdate() {}, updated() {}, beforeUnmount() {}, // new unmounted() {} } 

Bien que ces changements soient en rupture, ils peuvent être utilisés avec une version Vue compatible.

Cette API est également discutée et pourrait changer à l'avenir.

Résumé


À côté de l'innovation significative - l'API Composition - nous pouvons trouver plusieurs petites améliorations. De toute évidence, Vue s'oriente vers l'amélioration de l'expérience des développeurs, vers des API simplifiées et intuitives. C'est aussi cool de voir que l'équipe Vue a décidé d'ajouter beaucoup d'idées au cœur du cadre qui sont déjà implémentées dans des bibliothèques tierces.

La liste ci-dessus ne contient que les améliorations et modifications les plus importantes de l'API. Si vous souhaitez en savoir plus sur les autres, consultez le référentiel RFC .

Source: https://habr.com/ru/post/fr475968/


All Articles