Vue.js

Data-reactive web components

Bonjour, je m'appelle Eduardo et aujourd'hui je vais vous parler de vuejs. Un framework MVVM que j'ai découvert il y a quelques mois, que j'utilise depuis et lequel me plait de plus en plus.

Un autre MV* ?!

j'ai dit que c'était un framework MVVM. C'est vrai qu'il y en a plein. C'est comme si tout le monde avait vu Angular, s'était dit "C'est stylé de faire des applis comme ça, mais j'aimerais X" ou je n'aime pas Y". Et du coup tout le monde a eu envie de faire son propre Framework. Certains l'on fait, d'autres se sont dit qu'ils avaient pas le temps (la classique). Et du coup plus de 20 frameworks existent aujourd'hui. Tels que Angular, React, Aurelia, Angular2, Mithril et aussi Vuejs.

Pourquoi Vue ?

Et si je parle de Vuejs aujourd'hui c'est parce que ce framework établi un Equilibre entre performance et Usabilité. Je dirait meme qu'il arrive a trouver le compromis que React et Angular manquent. C'est orienté composants ou components en anglais. j'en reparlerai plus tard Issues crées tous les jours (un peu moins les we) et tout le monde qui répond chat Gitter pour discuter ou demander de l'aide Documentation solide tout ça pour componser un manque de questions sur stack overflow

Hello World

<div id="hello-world">
  <input v-model="value" type="text"/>
  <p>{{value}}</p>
</div>
new Vue({
  el: '#hello-world',
  data: {
    value: 'Hello World'
  }
});

{{value}}

On va directement passer à un hello world. Je vais à chaque fois

le code et le résultat à côté.

on créé un vm pour lier div et data, une directive pour input

Le Vocabulaire

Il y qq nouveaux mots. On va donc en parler Anvant de rentrer un peu plus dans les details de vue on va parler des principaux termes utilisés. Il y en a pas beaucoup :D

Les Directives

<input v-model="value" type="text"/>
Tous les v- sont des directives v-model est une directive mais type ne l est pas

Le View Model (vm)

View ⇆ Model

new Vue({...});
Le vm se charge de sync les données avec la vue La vm est crée quand on instancie une Vue Elle a toute la logique et ne comporte pas de manipulation du DOM(faites dans les directives)

Le View Model (vm)

Components

Modules réutilisables

<contact-card></contact-card>

Props

Données passées à un component

<contact-card featured></contact-card>
<contact-card type="rounded"></contact-card>
<contact-card v-bind:contact="contact"></contact-card>
ça va remplacer le ng-class et ng-checked et plein d'autres Ce qui est plus expressif car v-contact pourrait être une directive

Fontionnalités classiques

les impasses, mais avant on va parler des concepts de base de vue

Le v-show/v-if

<div id="v-show">
  <input v-model="show" type="checkbox"/>
  <span>
    {{show ? 'Hide the bear' : 'Show the bear'}}
  </span>
  <img v-show="show" src="images/bear-hello.gif"/>
</div>
new Vue({
  el: '#v-show',
  data: {
    show: false
  }
});

Le v-for

<div id="v-for">
  <ul>
    <li v-for="item in items">{{item}}</li>
  </ul>
</div>
new Vue({
  el: '#v-for',
  data: {
    items: [0, 1]
  }
});

There are {{items.length}} elements

  • {{item}}

Le transition

<div v-if="show" transition="expand">
  <img src="images/bear-hello.gif"/>
</div>
.expand-transition {
}
.expand-enter, .expand-leave {
}
.expand-transition {
  transition: all .3s ease;
  height: 220px;
  overflow: hidden;
}
.expand-enter, .expand-leave {
  height: 0;
  opacity: 0;
}

Le v-bind

<form v-bind:class="{'invalid-form': invalid}"></form>
<form :class="{'invalid-form': invalid}"></form>

Les Events(v-on)

<form v-on:submit="send()"></form>
<form @submit="send()"></form>
<button @click="select(contact)">Select</button>
Vue js fonctionne avec des events en interne. On peut emmettre des evenements sur des components qui remontent vers les parents

Les filtres

Adapter le modèle à la vue

<div id="filters">
  <p>{{obj | json}}</p>
</div>
new Vue({
  el: '#filters',
  data: {
    obj: {
      bool: true,
      arr: [1, 2],
      inner: {
        a: null
      }
    }
  }
});

{{obj | json}}

quand on veut modifier les données avant de les afficher on peut les chainer les un à la suite des autres On peut passer des argument et on peut bien sur creer ses propres filtres

C'est tout ?

Il manque bien sur plein de trucs. c'est pour ca que lon utilise des plugins. On evite de construire une usine a gaz

La consistence dans Vue

elles sont la pour faire que le dev n'ai pas a se poser de questions lorsqu'il doit écrire du code. réactif = prend une expression

Les Directives sont par défaut réactives

<a v-link="/foo">Go to foo</a>
<a v-link="'/foo'">Go to foo</a>
<a v-link.literal="/foo">Go to foo</a>
Tout ça dans le but d'être consistent et lisible

Les attributs et les props sont par défaut non réactifs

<img src="images/default-user.png"/>
<img :src="user.picture"/>
<contact-card :contact="user"></contact-card>
Ce qui a du sens pour les props car ça veut être la même chose vue sait que c'est un lien et qu'il faut faire une requete

Mustache binding

Pour interpoler du texte

<p>URL is {{imgUrl}}</p>

Component System

Les Avantages

j'ai parlé tout à l'heure des components comme un avantage. mais pourquoi ça incite la refacto car on peut bien commencer par un component qui contient tout Puis au fur et a mesure que l'appli avance on se rend compte que certain composants peuvent etre reutilisés

Tout dans une seule page

<div id="contacts">
  <form id="contacts-search" @submit="fetchResults()">
    <input v-model="search" type="text"/>
    <button type="submit">Search</button>
  </form>
  <div id="contacts-results" class="contacts-grid">
    <div class="contacts-card row" v-for="contact in contacts">
      <img :src="contact.imgUrl" class="contacts-img col-4"/>
      <div class="contacts-info col-8">
        <span>{{contact.firtsName}} {{contact.lastName}}</span>
      </div>
    </div>
  </div>
</div>

Components search et contact-grid

<div id="contacts">
  <search id="contacts-search" :submit="fetchResults"></search>
  <contact-grid id="contacts-results" :contacts="contacts">
  </contact-grid>
</div>
garde encore certains liens de données dans la vue pricipale

Componentception: contact-grid

<div class="contacts-grid">
  <contact-card v-for="contact in contacts"
    :contact="contact">
  </contact-card>
</div>

Binding modes

<mdl-checkbox :checked.sync="confirm">Confirm</mdl-checkbox>
Le sync est tres utile lorsque l'on crée des composants tels que des checkboxs

Les Hooks

created, beforeCompile, compiled, ...

ready: function() {
  componentHandler.upgradeElement(this.$el);
}

Le format .vue

il y a du template, du js et meme du style

Inline template

var MyComponent = Vue.extend({
    template: '

A custom component!

' });

Regrouper le template HTML avec le js

<template>
  <div class="contacts-card row" v-for="contact in contacts">
    <img :src="contact.imgUrl" class="contacts-img col-4"/>
    <div class="contacts-info col-8">
      <span>{{contact.firtsName}} {{contact.lastName}}</span>
    </div>
  </div>
</template>
<script>
module.exports = { props: { contact: { type: Object, required: true } } };
</script>

Regrouper le template Jade avec le Coffee

<template lang="jade">
.contacts-card.row(v-for'contact in contacts') img.contacts-img.col-4(:src='contact.imgUrl') .contacts-info.col-8 span {{contact.firtsName}} {{contact.lastName}}
</template>
<script lang="coffee">
module.exports = props: contact: type: Object required: true
</script>

Ajouter le style aussi

<template lang="jade">
...
</template>
<style lang="stylus">
.contacts-card ... .contacts-info ...
</style>
<script lang="coffee">
...
</script>

Transformer les .vue en .js

La suite



Merci !

de plus -> guide vuejs.org