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.

Eduardo San Martin Morote

Dev Theodo

posva

Another 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.

Why 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

Vocabulary

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

Directives

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

The 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)

The View Model (vm)

Components

Reusable modules

<contact-card></contact-card>

Props

Pass Data down to a component

<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

Usual features

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

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
  }
});

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}}

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;
}

v-bind

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

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

Filters

Adapt the model to the view

<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

That's all ?

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

The Rules

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

Directives are by default reactive

<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

Attributes and props are by default non reactive

<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

Text interpolation

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

Component System

Pros

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

One page mess

<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>

Search and contact-grid components

<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

Hooks

created, beforeCompile, compiled, ...

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

vue format

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

Inline template

var MyComponent = Vue.extend({
    template: '<p>I'm a component!</p>'
});

Gather your HTML with your 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>

Gather your pug(jade) with your js

<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>

Add the style

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

Compiling  vue filse into js

Going further



Thanks!

de plus -> guide vuejs.org