fullstack/vuejs

Auteur : J.C. Buisson
partie 1 - partie 2 - partie 3

VueJS - présentation générale

  • Vue ne gère… que la vue

  • les templates sont généralement à base html, mais pas nécessairement (ex: nativescript-vue)

  • les autres fonctions (routage, requêtes http, stockage centralisé de l’état, etc.) sont gérées dans des modules séparés, facilement pluggables

Premier exemple

index.html

  • l’exécution du script new Vue({... rend dynamique le template <div id="app">...</div>

  • la section data recense les données associées à ce bloc contrôlé par Vue, elles constituent l’état du composant

  • les expressions contenues dans les templates à moustache des parties text d’éléments html sont évaluées, et remplacées par leurs valeurs.
    L’expression peut être n’importe quelle expression javascript contenant des variables issues (entre-autres) de data

Deuxième exemple : double binding

index.html

<html>
  <div id="app">
    <h1> {{ name }} </h1>	
    <input v-model="name" placeholder="Enter your name" />
    <p>Hello, {{ name }}</p>
  </div>
</html>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<script>
new Vue({
   el: '#app',
   data: {
      name: ''
   }
})
</script>

L’attribut v-model="name" indique que this.name est le modèle de la vue que constitue l’input.

Cela signifie que, à chaque fois que this.name change, le contenu visible de l’input change, ainsi que le contenu visible des templates à moustache qui contiennent name (binding simple).
Inversement, chaque fois que l’utilisateur modifie le contenu de l’input en y éditant le texte, la valeur de this.name et des templates à moustache changent également de sorte que toutes les vues sont synchronisées sur le modèle this.name (double-binding).

En réalité, <input v-model="something"> est du sucre syntaxique pour :

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

data doit être une fonction

Si le champ data de la définition d’un composant est un simple objet, ses propriétés seront partagées par toutes les instances de ce composant (pourquoi ?), ce qui n’est pas souhaitable. data doit être une fonction qui renvoie un objet contenant les propriétés à accéder, par exemple :

Un attribut attr de data est accessible en lecture / écriture en tant que this.attr

Propriétés calculées (computed properties)

Exemple :

  • elles sont accessibles comme des propriétés ordinaires du composant this
  • elles apportent beaucoup de déclarativité aux composants Vue.
  • les propriétés calculées sont mises en cache selon leurs dépendances

Méthodes

À noter: L’écriture d’une méthode de composant methods ne doit pas utiliser les fat arrows car this ne sera alors par le composant lui-même, mais l’objet window

Événements

v-on:click="addItem"

Boucles et conditionnelles

https://codesandbox.io/s/jlo7p90lo5

index.html

Activité : édition d’une facture

Réaliser un formulaire de saisie d’items pour une facture selon le modèle suivant :

Composants et sous-composants

Instanciation d’un composant

  • un composant est une Vue paramétrable avec des propriétés props fournies par son composant père
  • une prop myprop d’un composant est accessible en lecture par this.myprop ; une tentative d’écriture provoque une erreur

Exemple

index.html

Modèle de communication entre composants

  • pour faire court : props down, events up
  • l’héritage des props ne va que du père vers le fils, il ne descend pas vers les petit-fils
  • un composant émet des événements que seul son père peut écouter (et pas son grand-père). Pour émettre un événement 'myevent' avec les paramètres param1, …, il faut appeler this.$emit('myevent', param1, ...)

Le modèle de communication est donc simple et bien cloisonné, strictement entre un père et son fils. Les propriétés descendent du père vers le fils, alors que des événements remontent du fils vers le père.

Single-file components

On peut décrire tous les éléments d’un composant (template, script, style) dans un même fichier d’extension .vue. Avec Webpack et son plugin vue-loader ces parties sont extraites et traitées séparément. Cela permet :

  • une édition simplifiée avec coloration syntaxique si on installe dans son IDE un plugin pour fichiers .vue
  • la transpilation de javascript ES6 ou ES7 avec Babel
  • des modules javascript CommonJS
  • un styling CSS dont le scope peut être restreint au composant
  • le hot-reload

La mise en place d’un tel système se fait simplement en utilisation vue-cli

npm install -g @vue/cli

vue create my-project
cd my-project
npm run serve

Activité: créer un éditeur Markdown

Utiliser le package marked

Noms de props et des événements dans les templates : kebab-case

Les noms des attributs en HTML sont case-insensitive. C’est la raison pour laquelle les noms de props et d’événements doivent être utilisés en forme kebab-case dans les templates .vue. Par exemple, si un composant a une section props: ['myProp],myPropdeviendramy-propdans l'instanciation du composant dans un template.vue:`

Activité

Refaire l’application d’édition de facture en utilisant au maximum une structure en composants, et en utilisant un fichier .vue par composant

Cycle de vie d’un composant Vue

On peut créer des hooks pour chacun de ces moments du cycle de vie, par exemple :

Exemple de toolkit de composants visuels : Vuetify

https://codesandbox.io/s/2pnvq5n3ln

index.js

index.html

App.vue

Activité : facture avec Vuetify

Améliorer le visuel de la facture avec Vuetify ou tout autre toolkit de composants graphiques

Installation vue + vuetify + webpack avec vue-cli

vue create my-project
cd my-project
vue add vuetify

À suivre: Partie 2