Vue.js - The Progressive JavaScript Framework

« Encore un framework de front ? »

« Qu’est-ce qu’il a de révolutionnaire celui-là ? »

« Je commence juste à maîtriser Angular (il ne faut plus dire Angular2, c’est tellement 2016), je ne vais pas me remettre à un autre framework ! »

Voici le genre de réactions auxquelles on se heurte quand on commence à évoquer Vue.js.

Et pourtant…

Pour commencer : présentons Vue.js

Vue.js (site officiel) est une implémentation du pattern MVVM (très bien présenté dans cet article), qui vient chasser sur les terres d’Angular. Il compte plusieurs concurrents : React, Angular 1 (déprécié), Angular 2, Ember, Knockout, Polymer, Riot, Aurelia.io, etc. Demain, il y en aura sûrement d’autres.

Son positionnement est d’être très peu contraignant. On peut l’utiliser sur tout ou partie de son site Web (incrementally adoptable). Les développeurs apprécient de n’être pas contraints sur l’organisation de leur projet (à la différence d’Angular qu’il faut adopter entièrement).

Sa syntaxe est inspirée de celle des custom-elements de la norme Web Components.

La simplicité d’apprentissage a été au coeur de la conception de Vue. Il est très rapide de démarrer une application Vue et de l’enrichir itérativement. L’ajout modulaire de librairies annexes permet d’assimiler au fur et à mesure les concepts en réduisant l’apprentissage aux éléments réellement utiles à l’application.

Les autres avantages mis en avant sont :

  • la taille : le module Vue.js core ne pèse que 17 ko compressé et minifié,
  • la performance ; voici une comparaison avec les principaux concurrents dans le tableau ci-dessous :

Source : http://www.stefankrause.net/wp/, données de Janvier 2017

Le module core est focalisé sur la couche présentation et ne nécessite de connaître que les langages de base du Web (HTML, JavaScript et CSS). Mais Vue.js a la bonne idée de supporter TypeScript, ce qui présente l’avantage de voir les erreurs avant la compilation.

Comme nous allons le voir, toutes les briques nécessaires pour construire une SPA (Single Page Application) digne de ce nom sont présentes dans Vue. Et plus encore.

Hello World!

First things first: un Hello World en Vue ça ressemble à ça !

Code HTML :

<divid="app"> {{ message }} </div>

Code Javascript :

var app =new Vue({ el: '#app', data: { message: 'Hello Vue!'}})

Output :

Hello Vue!

Sous le capot, Vue a construit sa représentation du Virtual DOM et lié les données. Notre application est maintenant réactive ! Pour preuve, on peut modifier la valeur de “app.message” dans la console JavaScript et le résultat est immédiat.

Le Virtual DOM est une représentation du DOM HTML sous forme d’objet JavaScript. L’idée est qu’il est beaucoup plus rapide de modifier un objet JS que le DOM HTML : on peut accéder directement à une propriété de l’objet JS, alors qu’il faut parcourir entièrement le DOM pour faire la même chose. Une explication plus claire est disponible dans l’article d’Anthony Gore dédié à l’exploitation du Virtual DOM par Vue.js.

La particularité d’une instance de Vue est qu’elle expose tous les champs trouvés dans l’objet “data”. Par exemple, dans le code HTML nous n’avons pas eu besoin de faire “data.message” pour accéder au texte.

En plus, de ces champs, l’instance de Vue expose un certain nombre de méthodes et de propriétés. Elles sont préfixées par un $ pour les différencier des champs provenant de data.

Par exemple :

app.$el ===document.getElementById('app')// -> true

Eléments de langage

Voici tous les éléments que nous avons à notre disposition pour construire une application complète.

  • interpolations : utiliser du texte ou du JavaScript qu’on peut associer à des éléments HTML.
  • directives : attributs spéciaux qui correspondent à des fonctions JavaScript, par exemple : v-if, v-bind, etc. - on peut définir des directives personnalisées globales ou locales ; par exemple, ici une directive globale qui modifie la couleur du texte ou du background :

Vue.directive('highlight', { bind(el, binding, vnode){if(binding.arg =='background'){ el.style.backgroundColor = binding.value; }else{ el.style.color = binding.value; }}});

invoqué depuis du HTML

<p v-highlight:background="'red'">Color this</p>

  • filters : permettent de chaîner des fonctions avec l’opérateur |, exemple : {{ message | capitalize }}

  • computed properties : l’avantage par rapport à une méthode est qu’une computed property est mise en cache, moins verbeux que watch et seulement recalculée si un élément source change.

  • watchers : utile dans certaines situations pour gérer l’asynchronisme.

  • binding html classes : permet de binder une classe à un élément HTML en fonction de la valeur d’un champ, par exemple <div v-bind:class="{ active: isActive }"></div>

  • conditionnal rendering : v-ifv-show qui ne fait que les masquer en utilisant un style. Il faut donc privilégier v-show, qui a un temps de chargement initial plus long, pour montrer et masquer fréquemment un objet, v-if sinon.

  • list : utilisation de v-for qui peut parcourir des objets d’un tableau, mais aussi des propriétés d’un objet.

  • event handling : utilisation de la directive v-on pour détecter les événements sur le DOM et y réagir.

  • form input binding : pour binder un composant sur un champ, il suffit d’utiliser la directive v-model, <input v-model="message" placeholder="edit me">

  • components : ils permettent d’étendre le langage HTML en définissant des balises gérées par Vue :- particularité, dans un composant, data doit être une fonction qui retourne un objet,

  • props : attribut custom pour passer des infos du conteneur père vers le composant fils (et uniquement dans ce sens là !),

  • custom events : dans un parent, on utilisera un custom event pour écouter un événement émis par un enfant,

  • non parent child communication : pour faire communiquer deux éléments qui n’ont pas de lien de parenté, on peut utiliser une instance de Vue comme bus ou utiliser Vuex.

  • composition : on utilise les éléments <slot> pour réserver des espaces à l’intérieur des composants :- par exemple, si on a un composant “app-layout” avec le template suivant :

<divclass="container"><header><slotname="header"></slot></header><main><slot></slot></main><footer><slotname="footer"></slot></footer></div>

  • et qu’on l’utilise avec le contenu suivant :

<app-layout><h1slot="header">Here might be a page title</h1><p>A paragraph for the main content.</p><p>And another one.</p><pslot="footer">Here's some contact info</p></app-layout>

  • on obtiendra ce résultat :

<divclass="container"><header><h1>Here might be a page title</h1></header><main><p>A paragraph for the main content.</p><p>And another one.</p></main><footer><p>Here's some contact info</p></footer></div>

Workflow de développement

Vue CLI permet d’initier un projet Vue selon 4 templates :

  • simple : index.html + Vue CDN import,
  • webpack-simple : utilisation webpack de base pour un démarrage rapide (recommandé),
  • webpack : utilisation webpack avancée avec linting, testing et extraction css,
  • browserify / browserify-simple : comme webpack mais avec browserify.

Prérequis : Node.js (>=4.x, 6.x de préférence), npm version 3+ et Git.

On peut aussi utiliser des templates présents sur GitHub directement depuis Vue CLI.

L’avantage d’utiliser webpack est qu’il s’impose comme un standard, puisqu’on l’utilise aussi avec Angular/CLI, par exemple.

Pour ajouter des composants à une application Vue, on peut utiliser le principe du single file component qui sera compilé en JS par webpack. Ce fichier d’extension .vue est découpé en 3 blocs :

  • template,
  • script,
  • style.

Comme on le voit, on peut définir simplement et intuitivement un composant en utilisant du HTML ou, comme ici, du jade pour le template et du stylus pour le style.

Pour débugger un projet Vue, deux options :

  • avec les Developer Tools de Chrome, on peut ouvrir le code shippé par webpack et mettre des points d’arrêts,
  • avec une extension Chrome Vue Developer Tools.

Modules d’extensions les plus utilisés

Vuex

Vuex  est une bibliothèque qui implémente une sous-partie de l’architecture Flux développée par Facebook. Elle permet de construire une SPA conséquente, constituée de composants avec des données partagées.

Vuex repose sur 3 principes :

  • Point de vérité unique : un data store unique pour partager les données entre les composants.
  • Données en lecture seule : un composant doit informer le store de son intention de modifier la donnée. Le store sera responsable d’appliquer le changement par un jeu de fonctions prédéfinies appelées “mutations”.
  • Les mutations sont synchrones : cela permet de garantir que l’état n’est pas dépendant de la séquence et de la temporalité d’évènements imprévisibles.

En garantissant les principes décrits ci-dessus, Vuex permet de maintenir les données applicatives dans un état transparent et prévisible, même lorsqu’elles sont partagées entre plusieurs composants.

Ce qui devient intéressant, c’est qu’en utilisant les computed properties de Vue pour obtenir une donnée stockée dans le store, Vue mettra à jour la computed properties à chaque fois que la donnée sera modifiée dans le store. L’application est d’autant plus réactive.

Vue-resource

vue-resource est un plugin pour effectuer des requêtes Web. Il utilise l’API Promise pour les réponses. Par exemple :

this.$http.post(‘url’, object) .then(response =>{ console.log(response)}, error =>{ console.log(error)});

Vue-router

vue-router est le plugin officiel pour organiser une SPA basée sur Vue.js. Il permet :

  • d’avoir un composant central pour gérer les routes,
  • de mettre en place des transitions et animations entre les composants,
  • de gérer l’association avec les classes CSS.

Pour conclure

Vue.js est une bonne corde à avoir à son arc en tant que développeur front-end. Ce framework permet de dynamiser très facilement une application Web existante ou de construire une SPA performante. La simplicité de prise en main bénéficie grandement de la modularité du framework : on ajoute des modules au fur et à mesure de ses besoins.

Finalement, il semble ne rien manquer à Vue.js. Donc pourquoi ne pas commencer à l’utiliser dès maintenant ?

Ressources

Remerciements

Merci à Sébastien Bergia pour ses précieuses contributions, à Vincent Beretti pour son étude sur les frameworks de front et à François Sarradin pour sa relecture attentive.